summaryrefslogtreecommitdiffstats
path: root/drivers/misc/sgi-xp/xpc.h
blob: 225f2bb84e39bb953d85d139cb09372b7d965fd8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (c) 2004-2009 Silicon Graphics, Inc.  All Rights Reserved.
 */

/*
 * Cross Partition Communication (XPC) structures and macros.
 */

#ifndef _DRIVERS_MISC_SGIXP_XPC_H
#define _DRIVERS_MISC_SGIXP_XPC_H

#include <linux/wait.h>
#include <linux/completion.h>
#include <linux/timer.h>
#include <linux/sched.h>
#include "xp.h"

/*
 * XPC Version numbers consist of a major and minor number. XPC can always
 * talk to versions with same major #, and never talk to versions with a
 * different major #.
 */
#define _XPC_VERSION(_maj, _min)	(((_maj) << 4) | ((_min) & 0xf))
#define XPC_VERSION_MAJOR(_v)		((_v) >> 4)
#define XPC_VERSION_MINOR(_v)		((_v) & 0xf)

/* define frequency of the heartbeat and frequency how often it's checked */
#define XPC_HB_DEFAULT_INTERVAL		5	/* incr HB every x secs */
#define XPC_HB_CHECK_DEFAULT_INTERVAL	20	/* check HB every x secs */

/* define the process name of HB checker and the CPU it is pinned to */
#define XPC_HB_CHECK_THREAD_NAME	"xpc_hb"
#define XPC_HB_CHECK_CPU		0

/* define the process name of the discovery thread */
#define XPC_DISCOVERY_THREAD_NAME	"xpc_discovery"

/*
 * the reserved page
 *
 *   SAL reserves one page of memory per partition for XPC. Though a full page
 *   in length (16384 bytes), its starting address is not page aligned, but it
 *   is cacheline aligned. The reserved page consists of the following:
 *
 *   reserved page header
 *
 *     The first two 64-byte cachelines of the reserved page contain the
 *     header (struct xpc_rsvd_page). Before SAL initialization has completed,
 *     SAL has set up the following fields of the reserved page header:
 *     SAL_signature, SAL_version, SAL_partid, and SAL_nasids_size. The
 *     other fields are set up by XPC. (xpc_rsvd_page points to the local
 *     partition's reserved page.)
 *
 *   part_nasids mask
 *   mach_nasids mask
 *
 *     SAL also sets up two bitmaps (or masks), one that reflects the actual
 *     nasids in this partition (part_nasids), and the other that reflects
 *     the actual nasids in the entire machine (mach_nasids). We're only
 *     interested in the even numbered nasids (which contain the processors
 *     and/or memory), so we only need half as many bits to represent the
 *     nasids. When mapping nasid to bit in a mask (or bit to nasid) be sure
 *     to either divide or multiply by 2. The part_nasids mask is located
 *     starting at the first cacheline following the reserved page header. The
 *     mach_nasids mask follows right after the part_nasids mask. The size in
 *     bytes of each mask is reflected by the reserved page header field
 *     'SAL_nasids_size'. (Local partition's mask pointers are xpc_part_nasids
 *     and xpc_mach_nasids.)
 *
 *     Immediately following the mach_nasids mask are the XPC variables
 *     required by other partitions. First are those that are generic to all
 *     partitions (vars), followed on the next available cacheline by those
 *     which are partition specific (vars part). These are setup by XPC.
 *
 * Note: Until 'ts_jiffies' is set non-zero, the partition XPC code has not been
 *       initialized.
 */
struct xpc_rsvd_page {
	u64 SAL_signature;	/* SAL: unique signature */
	u64 SAL_version;	/* SAL: version */
	short SAL_partid;	/* SAL: partition ID */
	short max_npartitions;	/* value of XPC_MAX_PARTITIONS */
	u8 version;
	u8 pad1[3];		/* align to next u64 in 1st 64-byte cacheline */
	unsigned long ts_jiffies; /* timestamp when rsvd pg was setup by XPC */
	union {
		struct {
			unsigned long heartbeat_gpa; /* phys addr */
			unsigned long activate_gru_mq_desc_gpa; /* phys addr */
		} uv;
	} sn;
	u64 pad2[9];		/* align to last u64 in 2nd 64-byte cacheline */
	u64 SAL_nasids_size;	/* SAL: size of each nasid mask in bytes */
};

#define XPC_RP_VERSION _XPC_VERSION(3, 0) /* version 3.0 of the reserved page */

/* the reserved page sizes and offsets */

#define XPC_RP_HEADER_SIZE	L1_CACHE_ALIGN(sizeof(struct xpc_rsvd_page))

#define XPC_RP_PART_NASIDS(_rp) ((unsigned long *)((u8 *)(_rp) + \
				 XPC_RP_HEADER_SIZE))
#define XPC_RP_MACH_NASIDS(_rp) (XPC_RP_PART_NASIDS(_rp) + \
				 xpc_nasid_mask_nlongs)


/*
 * The following structure describes the partition's heartbeat info which
 * will be periodically read by other partitions to determine whether this
 * XPC is still 'alive'.
 */
struct xpc_heartbeat_uv {
	unsigned long value;
	unsigned long offline;	/* if 0, heartbeat should be changing */
};

/*
 * Info pertinent to a GRU message queue using a watch list for irq generation.
 */
struct xpc_gru_mq_uv {
	void *address;		/* address of GRU message queue */
	unsigned int order;	/* size of GRU message queue as a power of 2 */
	int irq;		/* irq raised when message is received in mq */
	int mmr_blade;		/* blade where watchlist was allocated from */
	unsigned long mmr_offset; /* offset of irq mmr located on mmr_blade */
	unsigned long mmr_value; /* value of irq mmr located on mmr_blade */
	int watchlist_num;	/* number of watchlist allocatd by BIOS */
	void *gru_mq_desc;	/* opaque structure used by the GRU driver */
};

/*
 * The activate_mq is used to send/receive GRU messages that affect XPC's
 * partition active state and channel state. This is uv only.
 */
struct xpc_activate_mq_msghdr_uv {
	unsigned int gru_msg_hdr; /* FOR GRU INTERNAL USE ONLY */
	short partid;		/* sender's partid */
	u8 act_state;		/* sender's act_state at time msg sent */
	u8 type;		/* message's type */
	unsigned long rp_ts_jiffies; /* timestamp of sender's rp setup by XPC */
};

/* activate_mq defined message types */
#define XPC_ACTIVATE_MQ_MSG_SYNC_ACT_STATE_UV		0

#define XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV		1
#define XPC_ACTIVATE_MQ_MSG_DEACTIVATE_REQ_UV		2

#define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV	3
#define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV		4
#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV	5
#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV		6
#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV	7

#define XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV		8
#define XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV		9

struct xpc_activate_mq_msg_uv {
	struct xpc_activate_mq_msghdr_uv hdr;
};

struct xpc_activate_mq_msg_activate_req_uv {
	struct xpc_activate_mq_msghdr_uv hdr;
	unsigned long rp_gpa;
	unsigned long heartbeat_gpa;
	unsigned long activate_gru_mq_desc_gpa;
};

struct xpc_activate_mq_msg_deactivate_req_uv {
	struct xpc_activate_mq_msghdr_uv hdr;
	enum xp_retval reason;
};

struct xpc_activate_mq_msg_chctl_closerequest_uv {
	struct xpc_activate_mq_msghdr_uv hdr;
	short ch_number;
	enum xp_retval reason;
};

struct xpc_activate_mq_msg_chctl_closereply_uv {
	struct xpc_activate_mq_msghdr_uv hdr;
	short ch_number;
};

struct xpc_activate_mq_msg_chctl_openrequest_uv {
	struct xpc_activate_mq_msghdr_uv hdr;
	short ch_number;
	short entry_size;	/* size of notify_mq's GRU messages */
	short local_nentries;	/* ??? Is this needed? What is? */
};

struct xpc_activate_mq_msg_chctl_openreply_uv {
	struct xpc_activate_mq_msghdr_uv hdr;
	short ch_number;
	short remote_nentries;	/* ??? Is this needed? What is? */
	short local_nentries;	/* ??? Is this needed? What is? */
	unsigned long notify_gru_mq_desc_gpa;
};

struct xpc_activate_mq_msg_chctl_opencomplete_uv {
	struct xpc_activate_mq_msghdr_uv hdr;
	short ch_number;
};

/*
 * Functions registered by add_timer() or called by kernel_thread() only
 * allow for a single 64-bit argument. The following macros can be used to
 * pack and unpack two (32-bit, 16-bit or 8-bit) arguments into or out from
 * the passed argument.
 */
#define XPC_PACK_ARGS(_arg1, _arg2) \
			((((u64)_arg1) & 0xffffffff) | \
			((((u64)_arg2) & 0xffffffff) << 32))

#define XPC_UNPACK_ARG1(_args)	(((u64)_args) & 0xffffffff)
#define XPC_UNPACK_ARG2(_args)	((((u64)_args) >> 32) & 0xffffffff)

/*
 * Define a structure that contains arguments associated with opening and
 * closing a channel.
 */
struct xpc_openclose_args {
	u16 reason;		/* reason why channel is closing */
	u16 entry_size;		/* sizeof each message entry */
	u16 remote_nentries;	/* #of message entries in remote msg queue */
	u16 local_nentries;	/* #of message entries in local msg queue */
	unsigned long local_msgqueue_pa; /* phys addr of local message queue */
};

#define XPC_OPENCLOSE_ARGS_SIZE \
	      L1_CACHE_ALIGN(sizeof(struct xpc_openclose_args) * \
	      XPC_MAX_NCHANNELS)


/*
 * Structures to define a fifo singly-linked list.
 */

struct xpc_fifo_entry_uv {
	struct xpc_fifo_entry_uv *next;
};

struct xpc_fifo_head_uv {
	struct xpc_fifo_entry_uv *first;
	struct xpc_fifo_entry_uv *last;
	spinlock_t lock;
	int n_entries;
};

/*
 * The format of a uv XPC notify_mq GRU message is as follows:
 *
 * A user-defined message resides in the payload area. The max size of the
 * payload is defined by the user via xpc_connect().
 *
 * The size of a message (payload and header) sent via the GRU must be either 1
 * or 2 GRU_CACHE_LINE_BYTES in length.
 */

struct xpc_notify_mq_msghdr_uv {
	union {
		unsigned int gru_msg_hdr;	/* FOR GRU INTERNAL USE ONLY */
		struct xpc_fifo_entry_uv next;	/* FOR XPC INTERNAL USE ONLY */
	} u;
	short partid;		/* FOR XPC INTERNAL USE ONLY */
	u8 ch_number;		/* FOR XPC INTERNAL USE ONLY */
	u8 size;		/* FOR XPC INTERNAL USE ONLY */
	unsigned int msg_slot_number;	/* FOR XPC INTERNAL USE ONLY */
};

struct xpc_notify_mq_msg_uv {
	struct xpc_notify_mq_msghdr_uv hdr;
	unsigned long payload;
};

/* struct xpc_notify_sn2 type of notification */

#define	XPC_N_CALL	0x01	/* notify function provided by user */

/*
 * Define uv's version of the notify entry. It additionally is used to allocate
 * a msg slot on the remote partition into which is copied a sent message.
 */
struct xpc_send_msg_slot_uv {
	struct xpc_fifo_entry_uv next;
	unsigned int msg_slot_number;
	xpc_notify_func func;	/* user's notify function */
	void *key;		/* pointer to user's key */
};

/*
 * Define the structure that manages all the stuff required by a channel. In
 * particular, they are used to manage the messages sent across the channel.
 *
 * This structure is private to a partition, and is NOT shared across the
 * partition boundary.
 *
 * There is an array of these structures for each remote partition. It is
 * allocated at the time a partition becomes active. The array contains one
 * of these structures for each potential channel connection to that partition.
 */

struct xpc_channel_uv {
	void *cached_notify_gru_mq_desc; /* remote partition's notify mq's */
					 /* gru mq descriptor */

	struct xpc_send_msg_slot_uv *send_msg_slots;
	void *recv_msg_slots;	/* each slot will hold a xpc_notify_mq_msg_uv */
				/* structure plus the user's payload */

	struct xpc_fifo_head_uv msg_slot_free_list;
	struct xpc_fifo_head_uv recv_msg_list;	/* deliverable payloads */
};

struct xpc_channel {
	short partid;		/* ID of remote partition connected */
	spinlock_t lock;	/* lock for updating this structure */
	unsigned int