diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-07-08 06:24:13 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-08 06:24:13 -0400 |
commit | e3ae0acf59244ecf5b023ec99cef4b6b29d649bc (patch) | |
tree | 02a8bfdcab61677430ecfe04e9e44e1007c35f0e /include | |
parent | 4b62ac9a2b859f932afd5625362c927111b7dd9b (diff) | |
parent | e7eb8726d0e144f0925972c4ecee945e91a42753 (diff) |
Merge branch 'x86/uv' into x86/devel
Diffstat (limited to 'include')
-rw-r--r-- | include/asm-x86/atomic_64.h | 26 | ||||
-rw-r--r-- | include/asm-x86/mpspec.h | 7 | ||||
-rw-r--r-- | include/asm-x86/mpspec_def.h | 9 | ||||
-rw-r--r-- | include/asm-x86/uv/uv_bau.h | 337 |
4 files changed, 375 insertions, 4 deletions
diff --git a/include/asm-x86/atomic_64.h b/include/asm-x86/atomic_64.h index fe589c153db8..a0095191c02e 100644 --- a/include/asm-x86/atomic_64.h +++ b/include/asm-x86/atomic_64.h | |||
@@ -425,6 +425,32 @@ static inline int atomic64_add_unless(atomic64_t *v, long a, long u) | |||
425 | return c != (u); | 425 | return c != (u); |
426 | } | 426 | } |
427 | 427 | ||
428 | /** | ||
429 | * atomic_inc_short - increment of a short integer | ||
430 | * @v: pointer to type int | ||
431 | * | ||
432 | * Atomically adds 1 to @v | ||
433 | * Returns the new value of @u | ||
434 | */ | ||
435 | static inline short int atomic_inc_short(short int *v) | ||
436 | { | ||
437 | asm(LOCK_PREFIX "addw $1, %0" : "+m" (*v)); | ||
438 | return *v; | ||
439 | } | ||
440 | |||
441 | /** | ||
442 | * atomic_or_long - OR of two long integers | ||
443 | * @v1: pointer to type unsigned long | ||
444 | * @v2: pointer to type unsigned long | ||
445 | * | ||
446 | * Atomically ORs @v1 and @v2 | ||
447 | * Returns the result of the OR | ||
448 | */ | ||
449 | static inline void atomic_or_long(unsigned long *v1, unsigned long v2) | ||
450 | { | ||
451 | asm(LOCK_PREFIX "orq %1, %0" : "+m" (*v1) : "r" (v2)); | ||
452 | } | ||
453 | |||
428 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) | 454 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) |
429 | 455 | ||
430 | /* These are x86-specific, used by some header files */ | 456 | /* These are x86-specific, used by some header files */ |
diff --git a/include/asm-x86/mpspec.h b/include/asm-x86/mpspec.h index 6ec1a5453b3e..b6995e567fcc 100644 --- a/include/asm-x86/mpspec.h +++ b/include/asm-x86/mpspec.h | |||
@@ -122,6 +122,7 @@ typedef struct physid_mask physid_mask_t; | |||
122 | __physid_mask; \ | 122 | __physid_mask; \ |
123 | }) | 123 | }) |
124 | 124 | ||
125 | /* Note: will create very large stack frames if physid_mask_t is big */ | ||
125 | #define physid_mask_of_physid(physid) \ | 126 | #define physid_mask_of_physid(physid) \ |
126 | ({ \ | 127 | ({ \ |
127 | physid_mask_t __physid_mask = PHYSID_MASK_NONE; \ | 128 | physid_mask_t __physid_mask = PHYSID_MASK_NONE; \ |
@@ -129,6 +130,12 @@ typedef struct physid_mask physid_mask_t; | |||
129 | __physid_mask; \ | 130 | __physid_mask; \ |
130 | }) | 131 | }) |
131 | 132 | ||
133 | static inline void physid_set_mask_of_physid(int physid, physid_mask_t *map) | ||
134 | { | ||
135 | physids_clear(*map); | ||
136 | physid_set(physid, *map); | ||
137 | } | ||
138 | |||
132 | #define PHYSID_MASK_ALL { {[0 ... PHYSID_ARRAY_SIZE-1] = ~0UL} } | 139 | #define PHYSID_MASK_ALL { {[0 ... PHYSID_ARRAY_SIZE-1] = ~0UL} } |
133 | #define PHYSID_MASK_NONE { {[0 ... PHYSID_ARRAY_SIZE-1] = 0UL} } | 140 | #define PHYSID_MASK_NONE { {[0 ... PHYSID_ARRAY_SIZE-1] = 0UL} } |
134 | 141 | ||
diff --git a/include/asm-x86/mpspec_def.h b/include/asm-x86/mpspec_def.h index dc6ef85e3624..38d1e73b49e4 100644 --- a/include/asm-x86/mpspec_def.h +++ b/include/asm-x86/mpspec_def.h | |||
@@ -17,10 +17,11 @@ | |||
17 | # define MAX_MPC_ENTRY 1024 | 17 | # define MAX_MPC_ENTRY 1024 |
18 | # define MAX_APICS 256 | 18 | # define MAX_APICS 256 |
19 | #else | 19 | #else |
20 | /* | 20 | # if NR_CPUS <= 255 |
21 | * A maximum of 255 APICs with the current APIC ID architecture. | 21 | # define MAX_APICS 255 |
22 | */ | 22 | # else |
23 | # define MAX_APICS 255 | 23 | # define MAX_APICS 32768 |
24 | # endif | ||
24 | #endif | 25 | #endif |
25 | 26 | ||
26 | struct intel_mp_floating { | 27 | struct intel_mp_floating { |
diff --git a/include/asm-x86/uv/uv_bau.h b/include/asm-x86/uv/uv_bau.h new file mode 100644 index 000000000000..91ac0dfb7588 --- /dev/null +++ b/include/asm-x86/uv/uv_bau.h | |||
@@ -0,0 +1,337 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * SGI UV Broadcast Assist Unit definitions | ||
7 | * | ||
8 | * Copyright (C) 2008 Silicon Graphics, Inc. All rights reserved. | ||
9 | */ | ||
10 | |||
11 | #ifndef __ASM_X86_UV_BAU__ | ||
12 | #define __ASM_X86_UV_BAU__ | ||
13 | |||
14 | #include <linux/bitmap.h> | ||
15 | #define BITSPERBYTE 8 | ||
16 | |||
17 | /* | ||
18 | * Broadcast Assist Unit messaging structures | ||
19 | * | ||
20 | * Selective Broadcast activations are induced by software action | ||
21 | * specifying a particular 8-descriptor "set" via a 6-bit index written | ||
22 | * to an MMR. | ||
23 | * Thus there are 64 unique 512-byte sets of SB descriptors - one set for | ||
24 | * each 6-bit index value. These descriptor sets are mapped in sequence | ||
25 | * starting with set 0 located at the address specified in the | ||
26 | * BAU_SB_DESCRIPTOR_BASE register, set 1 is located at BASE + 512, | ||
27 | * set 2 is at BASE + 2*512, set 3 at BASE + 3*512, and so on. | ||
28 | * | ||
29 | * We will use 31 sets, one for sending BAU messages from each of the 32 | ||
30 | * cpu's on the node. | ||
31 | * | ||
32 | * TLB shootdown will use the first of the 8 descriptors of each set. | ||
33 | * Each of the descriptors is 64 bytes in size (8*64 = 512 bytes in a set). | ||
34 | */ | ||
35 | |||
36 | #define UV_ITEMS_PER_DESCRIPTOR 8 | ||
37 | #define UV_CPUS_PER_ACT_STATUS 32 | ||
38 | #define UV_ACT_STATUS_MASK 0x3 | ||
39 | #define UV_ACT_STATUS_SIZE 2 | ||
40 | #define UV_ACTIVATION_DESCRIPTOR_SIZE 32 | ||
41 | #define UV_DISTRIBUTION_SIZE 256 | ||
42 | #define UV_SW_ACK_NPENDING 8 | ||
43 | #define UV_BAU_MESSAGE 200 | ||
44 | /* | ||
45 | * Messaging irq; see irq_64.h and include/asm-x86/hw_irq_64.h | ||
46 | * To be dynamically allocated in the future | ||
47 | */ | ||
48 | #define UV_NET_ENDPOINT_INTD 0x38 | ||
49 | #define UV_DESC_BASE_PNODE_SHIFT 49 | ||
50 | #define UV_PAYLOADQ_PNODE_SHIFT 49 | ||
51 | #define UV_PTC_BASENAME "sgi_uv/ptc_statistics" | ||
52 | #define uv_physnodeaddr(x) ((__pa((unsigned long)(x)) & uv_mmask)) | ||
53 | |||
54 | /* | ||
55 | * bits in UVH_LB_BAU_SB_ACTIVATION_STATUS_0/1 | ||
56 | */ | ||
57 | #define DESC_STATUS_IDLE 0 | ||
58 | #define DESC_STATUS_ACTIVE 1 | ||
59 | #define DESC_STATUS_DESTINATION_TIMEOUT 2 | ||
60 | #define DESC_STATUS_SOURCE_TIMEOUT 3 | ||
61 | |||
62 | /* | ||
63 | * source side threshholds at which message retries print a warning | ||
64 | */ | ||
65 | #define SOURCE_TIMEOUT_LIMIT 20 | ||
66 | #define DESTINATION_TIMEOUT_LIMIT 20 | ||
67 | |||
68 | /* | ||
69 | * number of entries in the destination side payload queue | ||
70 | */ | ||
71 | #define DEST_Q_SIZE 17 | ||
72 | /* | ||
73 | * number of destination side software ack resources | ||
74 | */ | ||
75 | #define DEST_NUM_RESOURCES 8 | ||
76 | #define MAX_CPUS_PER_NODE 32 | ||
77 | /* | ||
78 | * completion statuses for sending a TLB flush message | ||
79 | */ | ||
80 | #define FLUSH_RETRY 1 | ||
81 | #define FLUSH_GIVEUP 2 | ||
82 | #define FLUSH_COMPLETE 3 | ||
83 | |||
84 | /* | ||
85 | * Distribution: 32 bytes (256 bits) (bytes 0-0x1f of descriptor) | ||
86 | * If the 'multilevel' flag in the header portion of the descriptor | ||
87 | * has been set to 0, then endpoint multi-unicast mode is selected. | ||
88 | * The distribution specification (32 bytes) is interpreted as a 256-bit | ||
89 | * distribution vector. Adjacent bits correspond to consecutive even numbered | ||
90 | * nodeIDs. The result of adding the index of a given bit to the 15-bit | ||
91 | * 'base_dest_nodeid' field of the header corresponds to the | ||
92 | * destination nodeID associated with that specified bit. | ||
93 | */ | ||
94 | struct bau_target_nodemask { | ||
95 | unsigned long bits[BITS_TO_LONGS(256)]; | ||
96 | }; | ||
97 | |||
98 | /* | ||
99 | * mask of cpu's on a node | ||
100 | * (during initialization we need to check that unsigned long has | ||
101 | * enough bits for max. cpu's per node) | ||
102 | */ | ||
103 | struct bau_local_cpumask { | ||
104 | unsigned long bits; | ||
105 | }; | ||
106 | |||
107 | /* | ||
108 | * Payload: 16 bytes (128 bits) (bytes 0x20-0x2f of descriptor) | ||
109 | * only 12 bytes (96 bits) of the payload area are usable. | ||
110 | * An additional 3 bytes (bits 27:4) of the header address are carried | ||
111 | * to the next bytes of the destination payload queue. | ||
112 | * And an additional 2 bytes of the header Suppl_A field are also | ||
113 | * carried to the destination payload queue. | ||
114 | * But the first byte of the Suppl_A becomes bits 127:120 (the 16th byte) | ||
115 | * of the destination payload queue, which is written by the hardware | ||
116 | * with the s/w ack resource bit vector. | ||
117 | * [ effective message contents (16 bytes (128 bits) maximum), not counting | ||
118 | * the s/w ack bit vector ] | ||
119 | */ | ||
120 | |||
121 | /* | ||
122 | * The payload is software-defined for INTD transactions | ||
123 | */ | ||
124 | struct bau_msg_payload { | ||
125 | unsigned long address; /* signifies a page or all TLB's | ||
126 | of the cpu */ | ||
127 | /* 64 bits */ | ||
128 | unsigned short sending_cpu; /* filled in by sender */ | ||
129 | /* 16 bits */ | ||
130 | unsigned short acknowledge_count;/* filled in by destination */ | ||
131 | /* 16 bits */ | ||
132 | unsigned int reserved1:32; /* not usable */ | ||
133 | }; | ||
134 | |||
135 | |||
136 | /* | ||
137 | * Message header: 16 bytes (128 bits) (bytes 0x30-0x3f of descriptor) | ||
138 | * see table 4.2.3.0.1 in broacast_assist spec. | ||
139 | */ | ||
140 | struct bau_msg_header { | ||
141 | int dest_subnodeid:6; /* must be zero */ | ||
142 | /* bits 5:0 */ | ||
143 | int base_dest_nodeid:15; /* nasid>>1 (pnode) of first bit in node_map */ | ||
144 | /* bits 20:6 */ | ||
145 | int command:8; /* message type */ | ||
146 | /* bits 28:21 */ | ||
147 | /* 0x38: SN3net EndPoint Message */ | ||
148 | int rsvd_1:3; /* must be zero */ | ||
149 | /* bits 31:29 */ | ||
150 | /* int will align on 32 bits */ | ||
151 | int rsvd_2:9; /* must be zero */ | ||
152 | /* bits 40:32 */ | ||
153 | /* Suppl_A is 56-41 */ | ||
154 | int payload_2a:8; /* becomes byte 16 of msg */ | ||
155 | /* bits 48:41 */ /* not currently using */ | ||
156 | int payload_2b:8; /* becomes byte 17 of msg */ | ||
157 | /* bits 56:49 */ /* not currently using */ | ||
158 | /* Address field (96:57) is never used as an | ||
159 | address (these are address bits 42:3) */ | ||
160 | int rsvd_3:1; /* must be zero */ | ||
161 | /* bit 57 */ | ||
162 | /* address bits 27:4 are payload */ | ||
163 | /* these 24 bits become bytes 12-14 of msg */ | ||
164 | int replied_to:1; /* sent as 0 by the source to byte 12 */ | ||
165 | /* bit 58 */ | ||
166 | |||
167 | int payload_1a:5; /* not currently used */ | ||
168 | /* bits 63:59 */ | ||
169 | int payload_1b:8; /* not currently used */ | ||
170 | /* bits 71:64 */ | ||
171 | int payload_1c:8; /* not currently used */ | ||
172 | /* bits 79:72 */ | ||
173 | int payload_1d:2; /* not currently used */ | ||
174 | /* bits 81:80 */ | ||
175 | |||
176 | int rsvd_4:7; /* must be zero */ | ||
177 | /* bits 88:82 */ | ||
178 | int sw_ack_flag:1; /* software acknowledge flag */ | ||
179 | /* bit 89 */ | ||
180 | /* INTD trasactions at destination are to | ||
181 | wait for software acknowledge */ | ||
182 | int rsvd_5:6; /* must be zero */ | ||
183 | /* bits 95:90 */ | ||
184 | int rsvd_6:5; /* must be zero */ | ||
185 | /* bits 100:96 */ | ||
186 | int int_both:1; /* if 1, interrupt both sockets on the blade */ | ||
187 | /* bit 101*/ | ||
188 | int fairness:3; /* usually zero */ | ||
189 | /* bits 104:102 */ | ||
190 | int multilevel:1; /* multi-level multicast format */ | ||
191 | /* bit 105 */ | ||
192 | /* 0 for TLB: endpoint multi-unicast messages */ | ||
193 | int chaining:1; /* next descriptor is part of this activation*/ | ||
194 | /* bit 106 */ | ||
195 | int rsvd_7:21; /* must be zero */ | ||
196 | /* bits 127:107 */ | ||
197 | }; | ||
198 | |||
199 | /* | ||
200 | * The activation descriptor: | ||
201 | * The format of the message to send, plus all accompanying control | ||
202 | * Should be 64 bytes | ||
203 | */ | ||
204 | struct bau_desc { | ||
205 | struct bau_target_nodemask distribution; | ||
206 | /* | ||
207 | * message template, consisting of header and payload: | ||
208 | */ | ||
209 | struct bau_msg_header header; | ||
210 | struct bau_msg_payload payload; | ||
211 | }; | ||
212 | /* | ||
213 | * -payload-- ---------header------ | ||
214 | * bytes 0-11 bits 41-56 bits 58-81 | ||
215 | * A B (2) C (3) | ||
216 | * | ||
217 | * A/B/C are moved to: | ||
218 | * A C B | ||
219 | * bytes 0-11 bytes 12-14 bytes 16-17 (byte 15 filled in by hw as vector) | ||
220 | * ------------payload queue----------- | ||
221 | */ | ||
222 | |||
223 | /* | ||
224 | * The payload queue on the destination side is an array of these. | ||
225 | * With BAU_MISC_CONTROL set for software acknowledge mode, the messages | ||
226 | * are 32 bytes (2 micropackets) (256 bits) in length, but contain only 17 | ||
227 | * bytes of usable data, including the sw ack vector in byte 15 (bits 127:120) | ||
228 | * (12 bytes come from bau_msg_payload, 3 from payload_1, 2 from | ||
229 | * sw_ack_vector and payload_2) | ||
230 | * "Enabling Software Acknowledgment mode (see Section 4.3.3 Software | ||
231 | * Acknowledge Processing) also selects 32 byte (17 bytes usable) payload | ||
232 | * operation." | ||
233 | */ | ||
234 | struct bau_payload_queue_entry { | ||
235 | unsigned long address; /* signifies a page or all TLB's | ||
236 | of the cpu */ | ||
237 | /* 64 bits, bytes 0-7 */ | ||
238 | |||
239 | unsigned short sending_cpu; /* cpu that sent the message */ | ||
240 | /* 16 bits, bytes 8-9 */ | ||
241 | |||
242 | unsigned short acknowledge_count; /* filled in by destination */ | ||
243 | /* 16 bits, bytes 10-11 */ | ||
244 | |||
245 | unsigned short replied_to:1; /* sent as 0 by the source */ | ||
246 | /* 1 bit */ | ||
247 | unsigned short unused1:7; /* not currently using */ | ||
248 | /* 7 bits: byte 12) */ | ||
249 | |||
250 | unsigned char unused2[2]; /* not currently using */ | ||
251 | /* bytes 13-14 */ | ||
252 | |||
253 | unsigned char sw_ack_vector; /* filled in by the hardware */ | ||
254 | /* byte 15 (bits 127:120) */ | ||
255 | |||
256 | unsigned char unused4[3]; /* not currently using bytes 17-19 */ | ||
257 | /* bytes 17-19 */ | ||
258 | |||
259 | int number_of_cpus; /* filled in at destination */ | ||
260 | /* 32 bits, bytes 20-23 (aligned) */ | ||
261 | |||
262 | unsigned char unused5[8]; /* not using */ | ||
263 | /* bytes 24-31 */ | ||
264 | }; | ||
265 | |||
266 | /* | ||
267 | * one for every slot in the destination payload queue | ||
268 | */ | ||
269 | struct bau_msg_status { | ||
270 | struct bau_local_cpumask seen_by; /* map of cpu's */ | ||
271 | }; | ||
272 | |||
273 | /* | ||
274 | * one for every slot in the destination software ack resources | ||
275 | */ | ||
276 | struct bau_sw_ack_status { | ||
277 | struct bau_payload_queue_entry *msg; /* associated message */ | ||
278 | int watcher; /* cpu monitoring, or -1 */ | ||
279 | }; | ||
280 | |||
281 | /* | ||
282 | * one on every node and per-cpu; to locate the software tables | ||
283 | */ | ||
284 | struct bau_control { | ||
285 | struct bau_desc *descriptor_base; | ||
286 | struct bau_payload_queue_entry *bau_msg_head; | ||
287 | struct bau_payload_queue_entry *va_queue_first; | ||
288 | struct bau_payload_queue_entry *va_queue_last; | ||
289 | struct bau_msg_status *msg_statuses; | ||
290 | int *watching; /* pointer to array */ | ||
291 | }; | ||
292 | |||
293 | /* | ||
294 | * This structure is allocated per_cpu for UV TLB shootdown statistics. | ||
295 | */ | ||
296 | struct ptc_stats { | ||
297 | unsigned long ptc_i; /* number of IPI-style flushes */ | ||
298 | unsigned long requestor; /* number of nodes this cpu sent to */ | ||
299 | unsigned long requestee; /* times cpu was remotely requested */ | ||
300 | unsigned long alltlb; /* times all tlb's on this cpu were flushed */ | ||
301 | unsigned long onetlb; /* times just one tlb on this cpu was flushed */ | ||
302 | unsigned long s_retry; /* retries on source side timeouts */ | ||
303 | unsigned long d_retry; /* retries on destination side timeouts */ | ||
304 | unsigned long sflush; /* cycles spent in uv_flush_tlb_others */ | ||
305 | unsigned long dflush; /* cycles spent on destination side */ | ||
306 | unsigned long retriesok; /* successes on retries */ | ||
307 | unsigned long nomsg; /* interrupts with no message */ | ||
308 | unsigned long multmsg; /* interrupts with multiple messages */ | ||
309 | unsigned long ntargeted;/* nodes targeted */ | ||
310 | }; | ||
311 | |||
312 | static inline int bau_node_isset(int node, struct bau_target_nodemask *dstp) | ||
313 | { | ||
314 | return constant_test_bit(node, &dstp->bits[0]); | ||
315 | } | ||
316 | static inline void bau_node_set(int node, struct bau_target_nodemask *dstp) | ||
317 | { | ||
318 | __set_bit(node, &dstp->bits[0]); | ||
319 | } | ||
320 | static inline void bau_nodes_clear(struct bau_target_nodemask *dstp, int nbits) | ||
321 | { | ||
322 | bitmap_zero(&dstp->bits[0], nbits); | ||
323 | } | ||
324 | |||
325 | static inline void bau_cpubits_clear(struct bau_local_cpumask *dstp, int nbits) | ||
326 | { | ||
327 | bitmap_zero(&dstp->bits, nbits); | ||
328 | } | ||
329 | |||
330 | #define cpubit_isset(cpu, bau_local_cpumask) \ | ||
331 | test_bit((cpu), (bau_local_cpumask).bits) | ||
332 | |||
333 | extern int uv_flush_tlb_others(cpumask_t *, struct mm_struct *, unsigned long); | ||
334 | extern void uv_bau_message_intr1(void); | ||
335 | extern void uv_bau_timeout_intr1(void); | ||
336 | |||
337 | #endif /* __ASM_X86_UV_BAU__ */ | ||