xref: /openbmc/linux/drivers/misc/sgi-xp/xpc.h (revision 93dc544c)
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  * Copyright (c) 2004-2008 Silicon Graphics, Inc.  All Rights Reserved.
7  */
8 
9 /*
10  * Cross Partition Communication (XPC) structures and macros.
11  */
12 
13 #ifndef _DRIVERS_MISC_SGIXP_XPC_H
14 #define _DRIVERS_MISC_SGIXP_XPC_H
15 
16 #include <linux/interrupt.h>
17 #include <linux/sysctl.h>
18 #include <linux/device.h>
19 #include <linux/mutex.h>
20 #include <linux/completion.h>
21 #include <asm/pgtable.h>
22 #include <asm/processor.h>
23 #include <asm/sn/bte.h>
24 #include <asm/sn/clksupport.h>
25 #include <asm/sn/addrs.h>
26 #include <asm/sn/mspec.h>
27 #include <asm/sn/shub_mmr.h>
28 #include "xp.h"
29 
30 /*
31  * XPC Version numbers consist of a major and minor number. XPC can always
32  * talk to versions with same major #, and never talk to versions with a
33  * different major #.
34  */
35 #define _XPC_VERSION(_maj, _min)	(((_maj) << 4) | ((_min) & 0xf))
36 #define XPC_VERSION_MAJOR(_v)		((_v) >> 4)
37 #define XPC_VERSION_MINOR(_v)		((_v) & 0xf)
38 
39 /*
40  * The next macros define word or bit representations for given
41  * C-brick nasid in either the SAL provided bit array representing
42  * nasids in the partition/machine or the AMO_t array used for
43  * inter-partition initiation communications.
44  *
45  * For SN2 machines, C-Bricks are alway even numbered NASIDs.  As
46  * such, some space will be saved by insisting that nasid information
47  * passed from SAL always be packed for C-Bricks and the
48  * cross-partition interrupts use the same packing scheme.
49  */
50 #define XPC_NASID_W_INDEX(_n)	(((_n) / 64) / 2)
51 #define XPC_NASID_B_INDEX(_n)	(((_n) / 2) & (64 - 1))
52 #define XPC_NASID_IN_ARRAY(_n, _p) ((_p)[XPC_NASID_W_INDEX(_n)] & \
53 				    (1UL << XPC_NASID_B_INDEX(_n)))
54 #define XPC_NASID_FROM_W_B(_w, _b) (((_w) * 64 + (_b)) * 2)
55 
56 #define XPC_HB_DEFAULT_INTERVAL		5	/* incr HB every x secs */
57 #define XPC_HB_CHECK_DEFAULT_INTERVAL	20	/* check HB every x secs */
58 
59 /* define the process name of HB checker and the CPU it is pinned to */
60 #define XPC_HB_CHECK_THREAD_NAME	"xpc_hb"
61 #define XPC_HB_CHECK_CPU		0
62 
63 /* define the process name of the discovery thread */
64 #define XPC_DISCOVERY_THREAD_NAME	"xpc_discovery"
65 
66 /*
67  * the reserved page
68  *
69  *   SAL reserves one page of memory per partition for XPC. Though a full page
70  *   in length (16384 bytes), its starting address is not page aligned, but it
71  *   is cacheline aligned. The reserved page consists of the following:
72  *
73  *   reserved page header
74  *
75  *     The first cacheline of the reserved page contains the header
76  *     (struct xpc_rsvd_page). Before SAL initialization has completed,
77  *     SAL has set up the following fields of the reserved page header:
78  *     SAL_signature, SAL_version, partid, and nasids_size. The other
79  *     fields are set up by XPC. (xpc_rsvd_page points to the local
80  *     partition's reserved page.)
81  *
82  *   part_nasids mask
83  *   mach_nasids mask
84  *
85  *     SAL also sets up two bitmaps (or masks), one that reflects the actual
86  *     nasids in this partition (part_nasids), and the other that reflects
87  *     the actual nasids in the entire machine (mach_nasids). We're only
88  *     interested in the even numbered nasids (which contain the processors
89  *     and/or memory), so we only need half as many bits to represent the
90  *     nasids. The part_nasids mask is located starting at the first cacheline
91  *     following the reserved page header. The mach_nasids mask follows right
92  *     after the part_nasids mask. The size in bytes of each mask is reflected
93  *     by the reserved page header field 'nasids_size'. (Local partition's
94  *     mask pointers are xpc_part_nasids and xpc_mach_nasids.)
95  *
96  *   vars
97  *   vars part
98  *
99  *     Immediately following the mach_nasids mask are the XPC variables
100  *     required by other partitions. First are those that are generic to all
101  *     partitions (vars), followed on the next available cacheline by those
102  *     which are partition specific (vars part). These are setup by XPC.
103  *     (Local partition's vars pointers are xpc_vars and xpc_vars_part.)
104  *
105  * Note: Until vars_pa is set, the partition XPC code has not been initialized.
106  */
107 struct xpc_rsvd_page {
108 	u64 SAL_signature;	/* SAL: unique signature */
109 	u64 SAL_version;	/* SAL: version */
110 	u8 partid;		/* SAL: partition ID */
111 	u8 version;
112 	u8 pad1[6];		/* align to next u64 in cacheline */
113 	u64 vars_pa;		/* physical address of struct xpc_vars */
114 	struct timespec stamp;	/* time when reserved page was setup by XPC */
115 	u64 pad2[9];		/* align to last u64 in cacheline */
116 	u64 nasids_size;	/* SAL: size of each nasid mask in bytes */
117 };
118 
119 #define XPC_RP_VERSION _XPC_VERSION(1, 1) /* version 1.1 of the reserved page */
120 
121 #define XPC_SUPPORTS_RP_STAMP(_version) \
122 			(_version >= _XPC_VERSION(1, 1))
123 
124 /*
125  * compare stamps - the return value is:
126  *
127  *	< 0,	if stamp1 < stamp2
128  *	= 0,	if stamp1 == stamp2
129  *	> 0,	if stamp1 > stamp2
130  */
131 static inline int
132 xpc_compare_stamps(struct timespec *stamp1, struct timespec *stamp2)
133 {
134 	int ret;
135 
136 	ret = stamp1->tv_sec - stamp2->tv_sec;
137 	if (ret == 0)
138 		ret = stamp1->tv_nsec - stamp2->tv_nsec;
139 
140 	return ret;
141 }
142 
143 /*
144  * Define the structures by which XPC variables can be exported to other
145  * partitions. (There are two: struct xpc_vars and struct xpc_vars_part)
146  */
147 
148 /*
149  * The following structure describes the partition generic variables
150  * needed by other partitions in order to properly initialize.
151  *
152  * struct xpc_vars version number also applies to struct xpc_vars_part.
153  * Changes to either structure and/or related functionality should be
154  * reflected by incrementing either the major or minor version numbers
155  * of struct xpc_vars.
156  */
157 struct xpc_vars {
158 	u8 version;
159 	u64 heartbeat;
160 	u64 heartbeating_to_mask;
161 	u64 heartbeat_offline;	/* if 0, heartbeat should be changing */
162 	int act_nasid;
163 	int act_phys_cpuid;
164 	u64 vars_part_pa;
165 	u64 amos_page_pa;	/* paddr of page of AMOs from MSPEC driver */
166 	AMO_t *amos_page;	/* vaddr of page of AMOs from MSPEC driver */
167 };
168 
169 #define XPC_V_VERSION _XPC_VERSION(3, 1)    /* version 3.1 of the cross vars */
170 
171 #define XPC_SUPPORTS_DISENGAGE_REQUEST(_version) \
172 			(_version >= _XPC_VERSION(3, 1))
173 
174 static inline int
175 xpc_hb_allowed(short partid, struct xpc_vars *vars)
176 {
177 	return ((vars->heartbeating_to_mask & (1UL << partid)) != 0);
178 }
179 
180 static inline void
181 xpc_allow_hb(short partid, struct xpc_vars *vars)
182 {
183 	u64 old_mask, new_mask;
184 
185 	do {
186 		old_mask = vars->heartbeating_to_mask;
187 		new_mask = (old_mask | (1UL << partid));
188 	} while (cmpxchg(&vars->heartbeating_to_mask, old_mask, new_mask) !=
189 		 old_mask);
190 }
191 
192 static inline void
193 xpc_disallow_hb(short partid, struct xpc_vars *vars)
194 {
195 	u64 old_mask, new_mask;
196 
197 	do {
198 		old_mask = vars->heartbeating_to_mask;
199 		new_mask = (old_mask & ~(1UL << partid));
200 	} while (cmpxchg(&vars->heartbeating_to_mask, old_mask, new_mask) !=
201 		 old_mask);
202 }
203 
204 /*
205  * The AMOs page consists of a number of AMO variables which are divided into
206  * four groups, The first two groups are used to identify an IRQ's sender.
207  * These two groups consist of 64 and 128 AMO variables respectively. The last
208  * two groups, consisting of just one AMO variable each, are used to identify
209  * the remote partitions that are currently engaged (from the viewpoint of
210  * the XPC running on the remote partition).
211  */
212 #define XPC_NOTIFY_IRQ_AMOS	   0
213 #define XPC_ACTIVATE_IRQ_AMOS	   (XPC_NOTIFY_IRQ_AMOS + XP_MAX_PARTITIONS)
214 #define XPC_ENGAGED_PARTITIONS_AMO (XPC_ACTIVATE_IRQ_AMOS + XP_NASID_MASK_WORDS)
215 #define XPC_DISENGAGE_REQUEST_AMO  (XPC_ENGAGED_PARTITIONS_AMO + 1)
216 
217 /*
218  * The following structure describes the per partition specific variables.
219  *
220  * An array of these structures, one per partition, will be defined. As a
221  * partition becomes active XPC will copy the array entry corresponding to
222  * itself from that partition. It is desirable that the size of this
223  * structure evenly divide into a cacheline, such that none of the entries
224  * in this array crosses a cacheline boundary. As it is now, each entry
225  * occupies half a cacheline.
226  */
227 struct xpc_vars_part {
228 	u64 magic;
229 
230 	u64 openclose_args_pa;	/* physical address of open and close args */
231 	u64 GPs_pa;		/* physical address of Get/Put values */
232 
233 	u64 IPI_amo_pa;		/* physical address of IPI AMO_t structure */
234 	int IPI_nasid;		/* nasid of where to send IPIs */
235 	int IPI_phys_cpuid;	/* physical CPU ID of where to send IPIs */
236 
237 	u8 nchannels;		/* #of defined channels supported */
238 
239 	u8 reserved[23];	/* pad to a full 64 bytes */
240 };
241 
242 /*
243  * The vars_part MAGIC numbers play a part in the first contact protocol.
244  *
245  * MAGIC1 indicates that the per partition specific variables for a remote
246  * partition have been initialized by this partition.
247  *
248  * MAGIC2 indicates that this partition has pulled the remote partititions
249  * per partition variables that pertain to this partition.
250  */
251 #define XPC_VP_MAGIC1	0x0053524156435058L   /* 'XPCVARS\0'L (little endian) */
252 #define XPC_VP_MAGIC2	0x0073726176435058L   /* 'XPCvars\0'L (little endian) */
253 
254 /* the reserved page sizes and offsets */
255 
256 #define XPC_RP_HEADER_SIZE	L1_CACHE_ALIGN(sizeof(struct xpc_rsvd_page))
257 #define XPC_RP_VARS_SIZE	L1_CACHE_ALIGN(sizeof(struct xpc_vars))
258 
259 #define XPC_RP_PART_NASIDS(_rp) ((u64 *)((u8 *)(_rp) + XPC_RP_HEADER_SIZE))
260 #define XPC_RP_MACH_NASIDS(_rp) (XPC_RP_PART_NASIDS(_rp) + xp_nasid_mask_words)
261 #define XPC_RP_VARS(_rp)	((struct xpc_vars *)(XPC_RP_MACH_NASIDS(_rp) + \
262 				    xp_nasid_mask_words))
263 #define XPC_RP_VARS_PART(_rp)	((struct xpc_vars_part *) \
264 				    ((u8 *)XPC_RP_VARS(_rp) + XPC_RP_VARS_SIZE))
265 
266 /*
267  * Functions registered by add_timer() or called by kernel_thread() only
268  * allow for a single 64-bit argument. The following macros can be used to
269  * pack and unpack two (32-bit, 16-bit or 8-bit) arguments into or out from
270  * the passed argument.
271  */
272 #define XPC_PACK_ARGS(_arg1, _arg2) \
273 			((((u64) _arg1) & 0xffffffff) | \
274 			((((u64) _arg2) & 0xffffffff) << 32))
275 
276 #define XPC_UNPACK_ARG1(_args)	(((u64) _args) & 0xffffffff)
277 #define XPC_UNPACK_ARG2(_args)	((((u64) _args) >> 32) & 0xffffffff)
278 
279 /*
280  * Define a Get/Put value pair (pointers) used with a message queue.
281  */
282 struct xpc_gp {
283 	s64 get;		/* Get value */
284 	s64 put;		/* Put value */
285 };
286 
287 #define XPC_GP_SIZE \
288 		L1_CACHE_ALIGN(sizeof(struct xpc_gp) * XPC_NCHANNELS)
289 
290 /*
291  * Define a structure that contains arguments associated with opening and
292  * closing a channel.
293  */
294 struct xpc_openclose_args {
295 	u16 reason;		/* reason why channel is closing */
296 	u16 msg_size;		/* sizeof each message entry */
297 	u16 remote_nentries;	/* #of message entries in remote msg queue */
298 	u16 local_nentries;	/* #of message entries in local msg queue */
299 	u64 local_msgqueue_pa;	/* physical address of local message queue */
300 };
301 
302 #define XPC_OPENCLOSE_ARGS_SIZE \
303 	      L1_CACHE_ALIGN(sizeof(struct xpc_openclose_args) * XPC_NCHANNELS)
304 
305 /* struct xpc_msg flags */
306 
307 #define	XPC_M_DONE		0x01	/* msg has been received/consumed */
308 #define	XPC_M_READY		0x02	/* msg is ready to be sent */
309 #define	XPC_M_INTERRUPT		0x04	/* send interrupt when msg consumed */
310 
311 #define XPC_MSG_ADDRESS(_payload) \
312 		((struct xpc_msg *)((u8 *)(_payload) - XPC_MSG_PAYLOAD_OFFSET))
313 
314 /*
315  * Defines notify entry.
316  *
317  * This is used to notify a message's sender that their message was received
318  * and consumed by the intended recipient.
319  */
320 struct xpc_notify {
321 	u8 type;		/* type of notification */
322 
323 	/* the following two fields are only used if type == XPC_N_CALL */
324 	xpc_notify_func func;	/* user's notify function */
325 	void *key;		/* pointer to user's key */
326 };
327 
328 /* struct xpc_notify type of notification */
329 
330 #define	XPC_N_CALL		0x01	/* notify function provided by user */
331 
332 /*
333  * Define the structure that manages all the stuff required by a channel. In
334  * particular, they are used to manage the messages sent across the channel.
335  *
336  * This structure is private to a partition, and is NOT shared across the
337  * partition boundary.
338  *
339  * There is an array of these structures for each remote partition. It is
340  * allocated at the time a partition becomes active. The array contains one
341  * of these structures for each potential channel connection to that partition.
342  *
343  * Each of these structures manages two message queues (circular buffers).
344  * They are allocated at the time a channel connection is made. One of
345  * these message queues (local_msgqueue) holds the locally created messages
346  * that are destined for the remote partition. The other of these message
347  * queues (remote_msgqueue) is a locally cached copy of the remote partition's
348  * own local_msgqueue.
349  *
350  * The following is a description of the Get/Put pointers used to manage these
351  * two message queues. Consider the local_msgqueue to be on one partition
352  * and the remote_msgqueue to be its cached copy on another partition. A
353  * description of what each of the lettered areas contains is included.
354  *
355  *
356  *                     local_msgqueue      remote_msgqueue
357  *
358  *                        |/////////|      |/////////|
359  *    w_remote_GP.get --> +---------+      |/////////|
360  *                        |    F    |      |/////////|
361  *     remote_GP.get  --> +---------+      +---------+ <-- local_GP->get
362  *                        |         |      |         |
363  *                        |         |      |    E    |
364  *                        |         |      |         |
365  *                        |         |      +---------+ <-- w_local_GP.get
366  *                        |    B    |      |/////////|
367  *                        |         |      |////D////|
368  *                        |         |      |/////////|
369  *                        |         |      +---------+ <-- w_remote_GP.put
370  *                        |         |      |////C////|
371  *      local_GP->put --> +---------+      +---------+ <-- remote_GP.put
372  *                        |         |      |/////////|
373  *                        |    A    |      |/////////|
374  *                        |         |      |/////////|
375  *     w_local_GP.put --> +---------+      |/////////|
376  *                        |/////////|      |/////////|
377  *
378  *
379  *	    ( remote_GP.[get|put] are cached copies of the remote
380  *	      partition's local_GP->[get|put], and thus their values can
381  *	      lag behind their counterparts on the remote partition. )
382  *
383  *
384  *  A - Messages that have been allocated, but have not yet been sent to the
385  *	remote partition.
386  *
387  *  B - Messages that have been sent, but have not yet been acknowledged by the
388  *      remote partition as having been received.
389  *
390  *  C - Area that needs to be prepared for the copying of sent messages, by
391  *	the clearing of the message flags of any previously received messages.
392  *
393  *  D - Area into which sent messages are to be copied from the remote
394  *	partition's local_msgqueue and then delivered to their intended
395  *	recipients. [ To allow for a multi-message copy, another pointer
396  *	(next_msg_to_pull) has been added to keep track of the next message
397  *	number needing to be copied (pulled). It chases after w_remote_GP.put.
398  *	Any messages lying between w_local_GP.get and next_msg_to_pull have
399  *	been copied and are ready to be delivered. ]
400  *
401  *  E - Messages that have been copied and delivered, but have not yet been
402  *	acknowledged by the recipient as having been received.
403  *
404  *  F - Messages that have been acknowledged, but XPC has not yet notified the
405  *	sender that the message was received by its intended recipient.
406  *	This is also an area that needs to be prepared for the allocating of
407  *	new messages, by the clearing of the message flags of the acknowledged
408  *	messages.
409  */
410 struct xpc_channel {
411 	short partid;		/* ID of remote partition connected */
412 	spinlock_t lock;	/* lock for updating this structure */
413 	u32 flags;		/* general flags */
414 
415 	enum xp_retval reason;	/* reason why channel is disconnect'g */
416 	int reason_line;	/* line# disconnect initiated from */
417 
418 	u16 number;		/* channel # */
419 
420 	u16 msg_size;		/* sizeof each msg entry */
421 	u16 local_nentries;	/* #of msg entries in local msg queue */
422 	u16 remote_nentries;	/* #of msg entries in remote msg queue */
423 
424 	void *local_msgqueue_base;	/* base address of kmalloc'd space */
425 	struct xpc_msg *local_msgqueue;	/* local message queue */
426 	void *remote_msgqueue_base;	/* base address of kmalloc'd space */
427 	struct xpc_msg *remote_msgqueue; /* cached copy of remote partition's */
428 					 /* local message queue */
429 	u64 remote_msgqueue_pa;	/* phys addr of remote partition's */
430 				/* local message queue */
431 
432 	atomic_t references;	/* #of external references to queues */
433 
434 	atomic_t n_on_msg_allocate_wq;	/* #on msg allocation wait queue */
435 	wait_queue_head_t msg_allocate_wq;	/* msg allocation wait queue */
436 
437 	u8 delayed_IPI_flags;	/* IPI flags received, but delayed */
438 				/* action until channel disconnected */
439 
440 	/* queue of msg senders who want to be notified when msg received */
441 
442 	atomic_t n_to_notify;	/* #of msg senders to notify */
443 	struct xpc_notify *notify_queue;    /* notify queue for messages sent */
444 
445 	xpc_channel_func func;	/* user's channel function */
446 	void *key;		/* pointer to user's key */
447 
448 	struct mutex msg_to_pull_mutex;	/* next msg to pull serialization */
449 	struct completion wdisconnect_wait;    /* wait for channel disconnect */
450 
451 	struct xpc_openclose_args *local_openclose_args; /* args passed on */
452 					     /* opening or closing of channel */
453 
454 	/* various flavors of local and remote Get/Put values */
455 
456 	struct xpc_gp *local_GP;	/* local Get/Put values */
457 	struct xpc_gp remote_GP;	/* remote Get/Put values */
458 	struct xpc_gp w_local_GP;	/* working local Get/Put values */
459 	struct xpc_gp w_remote_GP;	/* working remote Get/Put values */
460 	s64 next_msg_to_pull;	/* Put value of next msg to pull */
461 
462 	/* kthread management related fields */
463 
464 	atomic_t kthreads_assigned;	/* #of kthreads assigned to channel */
465 	u32 kthreads_assigned_limit;	/* limit on #of kthreads assigned */
466 	atomic_t kthreads_idle;	/* #of kthreads idle waiting for work */
467 	u32 kthreads_idle_limit;	/* limit on #of kthreads idle */
468 	atomic_t kthreads_active;	/* #of kthreads actively working */
469 
470 	wait_queue_head_t idle_wq;	/* idle kthread wait queue */
471 
472 } ____cacheline_aligned;
473 
474 /* struct xpc_channel flags */
475 
476 #define	XPC_C_WASCONNECTED	0x00000001	/* channel was connected */
477 
478 #define	XPC_C_ROPENREPLY	0x00000002	/* remote open channel reply */
479 #define	XPC_C_OPENREPLY		0x00000004	/* local open channel reply */
480 #define	XPC_C_ROPENREQUEST	0x00000008     /* remote open channel request */
481 #define	XPC_C_OPENREQUEST	0x00000010	/* local open channel request */
482 
483 #define	XPC_C_SETUP		0x00000020 /* channel's msgqueues are alloc'd */
484 #define	XPC_C_CONNECTEDCALLOUT	0x00000040     /* connected callout initiated */
485 #define	XPC_C_CONNECTEDCALLOUT_MADE \
486 				0x00000080     /* connected callout completed */
487 #define	XPC_C_CONNECTED		0x00000100	/* local channel is connected */
488 #define	XPC_C_CONNECTING	0x00000200	/* channel is being connected */
489 
490 #define	XPC_C_RCLOSEREPLY	0x00000400	/* remote close channel reply */
491 #define	XPC_C_CLOSEREPLY	0x00000800	/* local close channel reply */
492 #define	XPC_C_RCLOSEREQUEST	0x00001000    /* remote close channel request */
493 #define	XPC_C_CLOSEREQUEST	0x00002000     /* local close channel request */
494 
495 #define	XPC_C_DISCONNECTED	0x00004000	/* channel is disconnected */
496 #define	XPC_C_DISCONNECTING	0x00008000   /* channel is being disconnected */
497 #define	XPC_C_DISCONNECTINGCALLOUT \
498 				0x00010000 /* disconnecting callout initiated */
499 #define	XPC_C_DISCONNECTINGCALLOUT_MADE \
500 				0x00020000 /* disconnecting callout completed */
501 #define	XPC_C_WDISCONNECT	0x00040000  /* waiting for channel disconnect */
502 
503 /*
504  * Manages channels on a partition basis. There is one of these structures
505  * for each partition (a partition will never utilize the structure that
506  * represents itself).
507  */
508 struct xpc_partition {
509 
510 	/* XPC HB infrastructure */
511 
512 	u8 remote_rp_version;	/* version# of partition's rsvd pg */
513 	struct timespec remote_rp_stamp; /* time when rsvd pg was initialized */
514 	u64 remote_rp_pa;	/* phys addr of partition's rsvd pg */
515 	u64 remote_vars_pa;	/* phys addr of partition's vars */
516 	u64 remote_vars_part_pa;	/* phys addr of partition's vars part */
517 	u64 last_heartbeat;	/* HB at last read */
518 	u64 remote_amos_page_pa;	/* phys addr of partition's amos page */
519 	int remote_act_nasid;	/* active part's act/deact nasid */
520 	int remote_act_phys_cpuid;	/* active part's act/deact phys cpuid */
521 	u32 act_IRQ_rcvd;	/* IRQs since activation */
522 	spinlock_t act_lock;	/* protect updating of act_state */
523 	u8 act_state;		/* from XPC HB viewpoint */
524 	u8 remote_vars_version;	/* version# of partition's vars */
525 	enum xp_retval reason;	/* reason partition is deactivating */
526 	int reason_line;	/* line# deactivation initiated from */
527 	int reactivate_nasid;	/* nasid in partition to reactivate */
528 
529 	unsigned long disengage_request_timeout;	/* timeout in jiffies */
530 	struct timer_list disengage_request_timer;
531 
532 	/* XPC infrastructure referencing and teardown control */
533 
534 	u8 setup_state;		/* infrastructure setup state */
535 	wait_queue_head_t teardown_wq;	/* kthread waiting to teardown infra */
536 	atomic_t references;	/* #of references to infrastructure */
537 
538 	/*
539 	 * NONE OF THE PRECEDING FIELDS OF THIS STRUCTURE WILL BE CLEARED WHEN
540 	 * XPC SETS UP THE NECESSARY INFRASTRUCTURE TO SUPPORT CROSS PARTITION
541 	 * COMMUNICATION. ALL OF THE FOLLOWING FIELDS WILL BE CLEARED. (THE
542 	 * 'nchannels' FIELD MUST BE THE FIRST OF THE FIELDS TO BE CLEARED.)
543 	 */
544 
545 	u8 nchannels;		/* #of defined channels supported */
546 	atomic_t nchannels_active;  /* #of channels that are not DISCONNECTED */
547 	atomic_t nchannels_engaged;  /* #of channels engaged with remote part */
548 	struct xpc_channel *channels;	/* array of channel structures */
549 
550 	void *local_GPs_base;	/* base address of kmalloc'd space */
551 	struct xpc_gp *local_GPs;	/* local Get/Put values */
552 	void *remote_GPs_base;	/* base address of kmalloc'd space */
553 	struct xpc_gp *remote_GPs;	/* copy of remote partition's local */
554 					/* Get/Put values */
555 	u64 remote_GPs_pa;	/* phys address of remote partition's local */
556 				/* Get/Put values */
557 
558 	/* fields used to pass args when opening or closing a channel */
559 
560 	void *local_openclose_args_base;   /* base address of kmalloc'd space */
561 	struct xpc_openclose_args *local_openclose_args;      /* local's args */
562 	void *remote_openclose_args_base;  /* base address of kmalloc'd space */
563 	struct xpc_openclose_args *remote_openclose_args; /* copy of remote's */
564 							  /* args */
565 	u64 remote_openclose_args_pa;	/* phys addr of remote's args */
566 
567 	/* IPI sending, receiving and handling related fields */
568 
569 	int remote_IPI_nasid;	/* nasid of where to send IPIs */
570 	int remote_IPI_phys_cpuid;	/* phys CPU ID of where to send IPIs */
571 	AMO_t *remote_IPI_amo_va;    /* address of remote IPI AMO_t structure */
572 
573 	AMO_t *local_IPI_amo_va;	/* address of IPI AMO_t structure */
574 	u64 local_IPI_amo;	/* IPI amo flags yet to be handled */
575 	char IPI_owner[8];	/* IPI owner's name */
576 	struct timer_list dropped_IPI_timer;	/* dropped IPI timer */
577 
578 	spinlock_t IPI_lock;	/* IPI handler lock */
579 
580 	/* channel manager related fields */
581 
582 	atomic_t channel_mgr_requests;	/* #of requests to activate chan mgr */
583 	wait_queue_head_t channel_mgr_wq;	/* channel mgr's wait queue */
584 
585 } ____cacheline_aligned;
586 
587 /* struct xpc_partition act_state values (for XPC HB) */
588 
589 #define	XPC_P_INACTIVE		0x00	/* partition is not active */
590 #define XPC_P_ACTIVATION_REQ	0x01	/* created thread to activate */
591 #define XPC_P_ACTIVATING	0x02	/* activation thread started */
592 #define XPC_P_ACTIVE		0x03	/* xpc_partition_up() was called */
593 #define XPC_P_DEACTIVATING	0x04	/* partition deactivation initiated */
594 
595 #define XPC_DEACTIVATE_PARTITION(_p, _reason) \
596 			xpc_deactivate_partition(__LINE__, (_p), (_reason))
597 
598 /* struct xpc_partition setup_state values */
599 
600 #define XPC_P_UNSET		0x00	/* infrastructure was never setup */
601 #define XPC_P_SETUP		0x01	/* infrastructure is setup */
602 #define XPC_P_WTEARDOWN		0x02	/* waiting to teardown infrastructure */
603 #define XPC_P_TORNDOWN		0x03	/* infrastructure is torndown */
604 
605 /*
606  * struct xpc_partition IPI_timer #of seconds to wait before checking for
607  * dropped IPIs. These occur whenever an IPI amo write doesn't complete until
608  * after the IPI was received.
609  */
610 #define XPC_P_DROPPED_IPI_WAIT	(0.25 * HZ)
611 
612 /* number of seconds to wait for other partitions to disengage */
613 #define XPC_DISENGAGE_REQUEST_DEFAULT_TIMELIMIT	90
614 
615 /* interval in seconds to print 'waiting disengagement' messages */
616 #define XPC_DISENGAGE_PRINTMSG_INTERVAL		10
617 
618 #define XPC_PARTID(_p)	((short)((_p) - &xpc_partitions[0]))
619 
620 /* found in xp_main.c */
621 extern struct xpc_registration xpc_registrations[];
622 
623 /* found in xpc_main.c */
624 extern struct device *xpc_part;
625 extern struct device *xpc_chan;
626 extern int xpc_disengage_request_timelimit;
627 extern int xpc_disengage_request_timedout;
628 extern irqreturn_t xpc_notify_IRQ_handler(int, void *);
629 extern void xpc_dropped_IPI_check(struct xpc_partition *);
630 extern void xpc_activate_partition(struct xpc_partition *);
631 extern void xpc_activate_kthreads(struct xpc_channel *, int);
632 extern void xpc_create_kthreads(struct xpc_channel *, int, int);
633 extern void xpc_disconnect_wait(int);
634 
635 /* found in xpc_partition.c */
636 extern int xpc_exiting;
637 extern struct xpc_vars *xpc_vars;
638 extern struct xpc_rsvd_page *xpc_rsvd_page;
639 extern struct xpc_vars_part *xpc_vars_part;
640 extern struct xpc_partition xpc_partitions[XP_MAX_PARTITIONS + 1];
641 extern char *xpc_remote_copy_buffer;
642 extern void *xpc_remote_copy_buffer_base;
643 extern void *xpc_kmalloc_cacheline_aligned(size_t, gfp_t, void **);
644 extern struct xpc_rsvd_page *xpc_rsvd_page_init(void);
645 extern void xpc_allow_IPI_ops(void);
646 extern void xpc_restrict_IPI_ops(void);
647 extern int xpc_identify_act_IRQ_sender(void);
648 extern int xpc_partition_disengaged(struct xpc_partition *);
649 extern enum xp_retval xpc_mark_partition_active(struct xpc_partition *);
650 extern void xpc_mark_partition_inactive(struct xpc_partition *);
651 extern void xpc_discovery(void);
652 extern void xpc_check_remote_hb(void);
653 extern void xpc_deactivate_partition(const int, struct xpc_partition *,
654 				     enum xp_retval);
655 extern enum xp_retval xpc_initiate_partid_to_nasids(short, void *);
656 
657 /* found in xpc_channel.c */
658 extern void xpc_initiate_connect(int);
659 extern void xpc_initiate_disconnect(int);
660 extern enum xp_retval xpc_initiate_allocate(short, int, u32, void **);
661 extern enum xp_retval xpc_initiate_send(short, int, void *);
662 extern enum xp_retval xpc_initiate_send_notify(short, int, void *,
663 					       xpc_notify_func, void *);
664 extern void xpc_initiate_received(short, int, void *);
665 extern enum xp_retval xpc_setup_infrastructure(struct xpc_partition *);
666 extern enum xp_retval xpc_pull_remote_vars_part(struct xpc_partition *);
667 extern void xpc_process_channel_activity(struct xpc_partition *);
668 extern void xpc_connected_callout(struct xpc_channel *);
669 extern void xpc_deliver_msg(struct xpc_channel *);
670 extern void xpc_disconnect_channel(const int, struct xpc_channel *,
671 				   enum xp_retval, unsigned long *);
672 extern void xpc_disconnect_callout(struct xpc_channel *, enum xp_retval);
673 extern void xpc_partition_going_down(struct xpc_partition *, enum xp_retval);
674 extern void xpc_teardown_infrastructure(struct xpc_partition *);
675 
676 static inline void
677 xpc_wakeup_channel_mgr(struct xpc_partition *part)
678 {
679 	if (atomic_inc_return(&part->channel_mgr_requests) == 1)
680 		wake_up(&part->channel_mgr_wq);
681 }
682 
683 /*
684  * These next two inlines are used to keep us from tearing down a channel's
685  * msg queues while a thread may be referencing them.
686  */
687 static inline void
688 xpc_msgqueue_ref(struct xpc_channel *ch)
689 {
690 	atomic_inc(&ch->references);
691 }
692 
693 static inline void
694 xpc_msgqueue_deref(struct xpc_channel *ch)
695 {
696 	s32 refs = atomic_dec_return(&ch->references);
697 
698 	DBUG_ON(refs < 0);
699 	if (refs == 0)
700 		xpc_wakeup_channel_mgr(&xpc_partitions[ch->partid]);
701 }
702 
703 #define XPC_DISCONNECT_CHANNEL(_ch, _reason, _irqflgs) \
704 		xpc_disconnect_channel(__LINE__, _ch, _reason, _irqflgs)
705 
706 /*
707  * These two inlines are used to keep us from tearing down a partition's
708  * setup infrastructure while a thread may be referencing it.
709  */
710 static inline void
711 xpc_part_deref(struct xpc_partition *part)
712 {
713 	s32 refs = atomic_dec_return(&part->references);
714 
715 	DBUG_ON(refs < 0);
716 	if (refs == 0 && part->setup_state == XPC_P_WTEARDOWN)
717 		wake_up(&part->teardown_wq);
718 }
719 
720 static inline int
721 xpc_part_ref(struct xpc_partition *part)
722 {
723 	int setup;
724 
725 	atomic_inc(&part->references);
726 	setup = (part->setup_state == XPC_P_SETUP);
727 	if (!setup)
728 		xpc_part_deref(part);
729 
730 	return setup;
731 }
732 
733 /*
734  * The following macro is to be used for the setting of the reason and
735  * reason_line fields in both the struct xpc_channel and struct xpc_partition
736  * structures.
737  */
738 #define XPC_SET_REASON(_p, _reason, _line) \
739 	{ \
740 		(_p)->reason = _reason; \
741 		(_p)->reason_line = _line; \
742 	}
743 
744 /*
745  * This next set of inlines are used to keep track of when a partition is
746  * potentially engaged in accessing memory belonging to another partition.
747  */
748 
749 static inline void
750 xpc_mark_partition_engaged(struct xpc_partition *part)
751 {
752 	unsigned long irq_flags;
753 	AMO_t *amo = (AMO_t *)__va(part->remote_amos_page_pa +
754 				   (XPC_ENGAGED_PARTITIONS_AMO *
755 				    sizeof(AMO_t)));
756 
757 	local_irq_save(irq_flags);
758 
759 	/* set bit corresponding to our partid in remote partition's AMO */
760 	FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_OR,
761 			 (1UL << sn_partition_id));
762 	/*
763 	 * We must always use the nofault function regardless of whether we
764 	 * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
765 	 * didn't, we'd never know that the other partition is down and would
766 	 * keep sending IPIs and AMOs to it until the heartbeat times out.
767 	 */
768 	(void)xp_nofault_PIOR((u64 *)GLOBAL_MMR_ADDR(NASID_GET(&amo->
769 							       variable),
770 						     xp_nofault_PIOR_target));
771 
772 	local_irq_restore(irq_flags);
773 }
774 
775 static inline void
776 xpc_mark_partition_disengaged(struct xpc_partition *part)
777 {
778 	unsigned long irq_flags;
779 	AMO_t *amo = (AMO_t *)__va(part->remote_amos_page_pa +
780 				   (XPC_ENGAGED_PARTITIONS_AMO *
781 				    sizeof(AMO_t)));
782 
783 	local_irq_save(irq_flags);
784 
785 	/* clear bit corresponding to our partid in remote partition's AMO */
786 	FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND,
787 			 ~(1UL << sn_partition_id));
788 	/*
789 	 * We must always use the nofault function regardless of whether we
790 	 * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
791 	 * didn't, we'd never know that the other partition is down and would
792 	 * keep sending IPIs and AMOs to it until the heartbeat times out.
793 	 */
794 	(void)xp_nofault_PIOR((u64 *)GLOBAL_MMR_ADDR(NASID_GET(&amo->
795 							       variable),
796 						     xp_nofault_PIOR_target));
797 
798 	local_irq_restore(irq_flags);
799 }
800 
801 static inline void
802 xpc_request_partition_disengage(struct xpc_partition *part)
803 {
804 	unsigned long irq_flags;
805 	AMO_t *amo = (AMO_t *)__va(part->remote_amos_page_pa +
806 				   (XPC_DISENGAGE_REQUEST_AMO * sizeof(AMO_t)));
807 
808 	local_irq_save(irq_flags);
809 
810 	/* set bit corresponding to our partid in remote partition's AMO */
811 	FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_OR,
812 			 (1UL << sn_partition_id));
813 	/*
814 	 * We must always use the nofault function regardless of whether we
815 	 * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
816 	 * didn't, we'd never know that the other partition is down and would
817 	 * keep sending IPIs and AMOs to it until the heartbeat times out.
818 	 */
819 	(void)xp_nofault_PIOR((u64 *)GLOBAL_MMR_ADDR(NASID_GET(&amo->
820 							       variable),
821 						     xp_nofault_PIOR_target));
822 
823 	local_irq_restore(irq_flags);
824 }
825 
826 static inline void
827 xpc_cancel_partition_disengage_request(struct xpc_partition *part)
828 {
829 	unsigned long irq_flags;
830 	AMO_t *amo = (AMO_t *)__va(part->remote_amos_page_pa +
831 				   (XPC_DISENGAGE_REQUEST_AMO * sizeof(AMO_t)));
832 
833 	local_irq_save(irq_flags);
834 
835 	/* clear bit corresponding to our partid in remote partition's AMO */
836 	FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND,
837 			 ~(1UL << sn_partition_id));
838 	/*
839 	 * We must always use the nofault function regardless of whether we
840 	 * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
841 	 * didn't, we'd never know that the other partition is down and would
842 	 * keep sending IPIs and AMOs to it until the heartbeat times out.
843 	 */
844 	(void)xp_nofault_PIOR((u64 *)GLOBAL_MMR_ADDR(NASID_GET(&amo->
845 							       variable),
846 						     xp_nofault_PIOR_target));
847 
848 	local_irq_restore(irq_flags);
849 }
850 
851 static inline u64
852 xpc_partition_engaged(u64 partid_mask)
853 {
854 	AMO_t *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO;
855 
856 	/* return our partition's AMO variable ANDed with partid_mask */
857 	return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) &
858 		partid_mask);
859 }
860 
861 static inline u64
862 xpc_partition_disengage_requested(u64 partid_mask)
863 {
864 	AMO_t *amo = xpc_vars->amos_page + XPC_DISENGAGE_REQUEST_AMO;
865 
866 	/* return our partition's AMO variable ANDed with partid_mask */
867 	return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) &
868 		partid_mask);
869 }
870 
871 static inline void
872 xpc_clear_partition_engaged(u64 partid_mask)
873 {
874 	AMO_t *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO;
875 
876 	/* clear bit(s) based on partid_mask in our partition's AMO */
877 	FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND,
878 			 ~partid_mask);
879 }
880 
881 static inline void
882 xpc_clear_partition_disengage_request(u64 partid_mask)
883 {
884 	AMO_t *amo = xpc_vars->amos_page + XPC_DISENGAGE_REQUEST_AMO;
885 
886 	/* clear bit(s) based on partid_mask in our partition's AMO */
887 	FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND,
888 			 ~partid_mask);
889 }
890 
891 /*
892  * The following set of macros and inlines are used for the sending and
893  * receiving of IPIs (also known as IRQs). There are two flavors of IPIs,
894  * one that is associated with partition activity (SGI_XPC_ACTIVATE) and
895  * the other that is associated with channel activity (SGI_XPC_NOTIFY).
896  */
897 
898 static inline u64
899 xpc_IPI_receive(AMO_t *amo)
900 {
901 	return FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_CLEAR);
902 }
903 
904 static inline enum xp_retval
905 xpc_IPI_send(AMO_t *amo, u64 flag, int nasid, int phys_cpuid, int vector)
906 {
907 	int ret = 0;
908 	unsigned long irq_flags;
909 
910 	local_irq_save(irq_flags);
911 
912 	FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_OR, flag);
913 	sn_send_IPI_phys(nasid, phys_cpuid, vector, 0);
914 
915 	/*
916 	 * We must always use the nofault function regardless of whether we
917 	 * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
918 	 * didn't, we'd never know that the other partition is down and would
919 	 * keep sending IPIs and AMOs to it until the heartbeat times out.
920 	 */
921 	ret = xp_nofault_PIOR((u64 *)GLOBAL_MMR_ADDR(NASID_GET(&amo->variable),
922 						     xp_nofault_PIOR_target));
923 
924 	local_irq_restore(irq_flags);
925 
926 	return ((ret == 0) ? xpSuccess : xpPioReadError);
927 }
928 
929 /*
930  * IPIs associated with SGI_XPC_ACTIVATE IRQ.
931  */
932 
933 /*
934  * Flag the appropriate AMO variable and send an IPI to the specified node.
935  */
936 static inline void
937 xpc_activate_IRQ_send(u64 amos_page_pa, int from_nasid, int to_nasid,
938 		      int to_phys_cpuid)
939 {
940 	int w_index = XPC_NASID_W_INDEX(from_nasid);
941 	int b_index = XPC_NASID_B_INDEX(from_nasid);
942 	AMO_t *amos = (AMO_t *)__va(amos_page_pa +
943 				    (XPC_ACTIVATE_IRQ_AMOS * sizeof(AMO_t)));
944 
945 	(void)xpc_IPI_send(&amos[w_index], (1UL << b_index), to_nasid,
946 			   to_phys_cpuid, SGI_XPC_ACTIVATE);
947 }
948 
949 static inline void
950 xpc_IPI_send_activate(struct xpc_vars *vars)
951 {
952 	xpc_activate_IRQ_send(vars->amos_page_pa, cnodeid_to_nasid(0),
953 			      vars->act_nasid, vars->act_phys_cpuid);
954 }
955 
956 static inline void
957 xpc_IPI_send_activated(struct xpc_partition *part)
958 {
959 	xpc_activate_IRQ_send(part->remote_amos_page_pa, cnodeid_to_nasid(0),
960 			      part->remote_act_nasid,
961 			      part->remote_act_phys_cpuid);
962 }
963 
964 static inline void
965 xpc_IPI_send_reactivate(struct xpc_partition *part)
966 {
967 	xpc_activate_IRQ_send(xpc_vars->amos_page_pa, part->reactivate_nasid,
968 			      xpc_vars->act_nasid, xpc_vars->act_phys_cpuid);
969 }
970 
971 static inline void
972 xpc_IPI_send_disengage(struct xpc_partition *part)
973 {
974 	xpc_activate_IRQ_send(part->remote_amos_page_pa, cnodeid_to_nasid(0),
975 			      part->remote_act_nasid,
976 			      part->remote_act_phys_cpuid);
977 }
978 
979 /*
980  * IPIs associated with SGI_XPC_NOTIFY IRQ.
981  */
982 
983 /*
984  * Send an IPI to the remote partition that is associated with the
985  * specified channel.
986  */
987 #define XPC_NOTIFY_IRQ_SEND(_ch, _ipi_f, _irq_f) \
988 		xpc_notify_IRQ_send(_ch, _ipi_f, #_ipi_f, _irq_f)
989 
990 static inline void
991 xpc_notify_IRQ_send(struct xpc_channel *ch, u8 ipi_flag, char *ipi_flag_string,
992 		    unsigned long *irq_flags)
993 {
994 	struct xpc_partition *part = &xpc_partitions[ch->partid];
995 	enum xp_retval ret;
996 
997 	if (likely(part->act_state != XPC_P_DEACTIVATING)) {
998 		ret = xpc_IPI_send(part->remote_IPI_amo_va,
999 				   (u64)ipi_flag << (ch->number * 8),
1000 				   part->remote_IPI_nasid,
1001 				   part->remote_IPI_phys_cpuid, SGI_XPC_NOTIFY);
1002 		dev_dbg(xpc_chan, "%s sent to partid=%d, channel=%d, ret=%d\n",
1003 			ipi_flag_string, ch->partid, ch->number, ret);
1004 		if (unlikely(ret != xpSuccess)) {
1005 			if (irq_flags != NULL)
1006 				spin_unlock_irqrestore(&ch->lock, *irq_flags);
1007 			XPC_DEACTIVATE_PARTITION(part, ret);
1008 			if (irq_flags != NULL)
1009 				spin_lock_irqsave(&ch->lock, *irq_flags);
1010 		}
1011 	}
1012 }
1013 
1014 /*
1015  * Make it look like the remote partition, which is associated with the
1016  * specified channel, sent us an IPI. This faked IPI will be handled
1017  * by xpc_dropped_IPI_check().
1018  */
1019 #define XPC_NOTIFY_IRQ_SEND_LOCAL(_ch, _ipi_f) \
1020 		xpc_notify_IRQ_send_local(_ch, _ipi_f, #_ipi_f)
1021 
1022 static inline void
1023 xpc_notify_IRQ_send_local(struct xpc_channel *ch, u8 ipi_flag,
1024 			  char *ipi_flag_string)
1025 {
1026 	struct xpc_partition *part = &xpc_partitions[ch->partid];
1027 
1028 	FETCHOP_STORE_OP(TO_AMO((u64)&part->local_IPI_amo_va->variable),
1029 			 FETCHOP_OR, ((u64)ipi_flag << (ch->number * 8)));
1030 	dev_dbg(xpc_chan, "%s sent local from partid=%d, channel=%d\n",
1031 		ipi_flag_string, ch->partid, ch->number);
1032 }
1033 
1034 /*
1035  * The sending and receiving of IPIs includes the setting of an AMO variable
1036  * to indicate the reason the IPI was sent. The 64-bit variable is divided
1037  * up into eight bytes, ordered from right to left. Byte zero pertains to
1038  * channel 0, byte one to channel 1, and so on. Each byte is described by
1039  * the following IPI flags.
1040  */
1041 
1042 #define	XPC_IPI_CLOSEREQUEST	0x01
1043 #define	XPC_IPI_CLOSEREPLY	0x02
1044 #define	XPC_IPI_OPENREQUEST	0x04
1045 #define	XPC_IPI_OPENREPLY	0x08
1046 #define	XPC_IPI_MSGREQUEST	0x10
1047 
1048 /* given an AMO variable and a channel#, get its associated IPI flags */
1049 #define XPC_GET_IPI_FLAGS(_amo, _c)	((u8) (((_amo) >> ((_c) * 8)) & 0xff))
1050 #define XPC_SET_IPI_FLAGS(_amo, _c, _f)	(_amo) |= ((u64) (_f) << ((_c) * 8))
1051 
1052 #define	XPC_ANY_OPENCLOSE_IPI_FLAGS_SET(_amo) ((_amo) & 0x0f0f0f0f0f0f0f0fUL)
1053 #define XPC_ANY_MSG_IPI_FLAGS_SET(_amo)       ((_amo) & 0x1010101010101010UL)
1054 
1055 static inline void
1056 xpc_IPI_send_closerequest(struct xpc_channel *ch, unsigned long *irq_flags)
1057 {
1058 	struct xpc_openclose_args *args = ch->local_openclose_args;
1059 
1060 	args->reason = ch->reason;
1061 
1062 	XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_CLOSEREQUEST, irq_flags);
1063 }
1064 
1065 static inline void
1066 xpc_IPI_send_closereply(struct xpc_channel *ch, unsigned long *irq_flags)
1067 {
1068 	XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_CLOSEREPLY, irq_flags);
1069 }
1070 
1071 static inline void
1072 xpc_IPI_send_openrequest(struct xpc_channel *ch, unsigned long *irq_flags)
1073 {
1074 	struct xpc_openclose_args *args = ch->local_openclose_args;
1075 
1076 	args->msg_size = ch->msg_size;
1077 	args->local_nentries = ch->local_nentries;
1078 
1079 	XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_OPENREQUEST, irq_flags);
1080 }
1081 
1082 static inline void
1083 xpc_IPI_send_openreply(struct xpc_channel *ch, unsigned long *irq_flags)
1084 {
1085 	struct xpc_openclose_args *args = ch->local_openclose_args;
1086 
1087 	args->remote_nentries = ch->remote_nentries;
1088 	args->local_nentries = ch->local_nentries;
1089 	args->local_msgqueue_pa = __pa(ch->local_msgqueue);
1090 
1091 	XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_OPENREPLY, irq_flags);
1092 }
1093 
1094 static inline void
1095 xpc_IPI_send_msgrequest(struct xpc_channel *ch)
1096 {
1097 	XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_MSGREQUEST, NULL);
1098 }
1099 
1100 static inline void
1101 xpc_IPI_send_local_msgrequest(struct xpc_channel *ch)
1102 {
1103 	XPC_NOTIFY_IRQ_SEND_LOCAL(ch, XPC_IPI_MSGREQUEST);
1104 }
1105 
1106 /*
1107  * Memory for XPC's AMO variables is allocated by the MSPEC driver. These
1108  * pages are located in the lowest granule. The lowest granule uses 4k pages
1109  * for cached references and an alternate TLB handler to never provide a
1110  * cacheable mapping for the entire region. This will prevent speculative
1111  * reading of cached copies of our lines from being issued which will cause
1112  * a PI FSB Protocol error to be generated by the SHUB. For XPC, we need 64
1113  * AMO variables (based on XP_MAX_PARTITIONS) for message notification and an
1114  * additional 128 AMO variables (based on XP_NASID_MASK_WORDS) for partition
1115  * activation and 2 AMO variables for partition deactivation.
1116  */
1117 static inline AMO_t *
1118 xpc_IPI_init(int index)
1119 {
1120 	AMO_t *amo = xpc_vars->amos_page + index;
1121 
1122 	(void)xpc_IPI_receive(amo);	/* clear AMO variable */
1123 	return amo;
1124 }
1125 
1126 static inline enum xp_retval
1127 xpc_map_bte_errors(bte_result_t error)
1128 {
1129 	return ((error == BTE_SUCCESS) ? xpSuccess : xpBteCopyError);
1130 }
1131 
1132 /*
1133  * Check to see if there is any channel activity to/from the specified
1134  * partition.
1135  */
1136 static inline void
1137 xpc_check_for_channel_activity(struct xpc_partition *part)
1138 {
1139 	u64 IPI_amo;
1140 	unsigned long irq_flags;
1141 
1142 	IPI_amo = xpc_IPI_receive(part->local_IPI_amo_va);
1143 	if (IPI_amo == 0)
1144 		return;
1145 
1146 	spin_lock_irqsave(&part->IPI_lock, irq_flags);
1147 	part->local_IPI_amo |= IPI_amo;
1148 	spin_unlock_irqrestore(&part->IPI_lock, irq_flags);
1149 
1150 	dev_dbg(xpc_chan, "received IPI from partid=%d, IPI_amo=0x%lx\n",
1151 		XPC_PARTID(part), IPI_amo);
1152 
1153 	xpc_wakeup_channel_mgr(part);
1154 }
1155 
1156 #endif /* _DRIVERS_MISC_SGIXP_XPC_H */
1157