145d9ca49SDean Nelson /*
245d9ca49SDean Nelson * This file is subject to the terms and conditions of the GNU General Public
345d9ca49SDean Nelson * License. See the file "COPYING" in the main directory of this archive
445d9ca49SDean Nelson * for more details.
545d9ca49SDean Nelson *
6*7a6d94f0SMike Travis * (C) Copyright 2020 Hewlett Packard Enterprise Development LP
745d9ca49SDean Nelson * Copyright (C) 2004-2008 Silicon Graphics, Inc. All rights reserved.
845d9ca49SDean Nelson */
945d9ca49SDean Nelson
1045d9ca49SDean Nelson /*
1145d9ca49SDean Nelson * External Cross Partition (XP) structures and defines.
1245d9ca49SDean Nelson */
1345d9ca49SDean Nelson
1445d9ca49SDean Nelson #ifndef _DRIVERS_MISC_SGIXP_XP_H
1545d9ca49SDean Nelson #define _DRIVERS_MISC_SGIXP_XP_H
1645d9ca49SDean Nelson
1745d9ca49SDean Nelson #include <linux/mutex.h>
1845d9ca49SDean Nelson
191c004004SDean Nelson #if defined CONFIG_X86_UV || defined CONFIG_IA64_SGI_UV
205b221278SIngo Molnar #include <asm/uv/uv.h>
211c004004SDean Nelson #endif
221c004004SDean Nelson
23261f3b49SDean Nelson #ifdef USE_DBUG_ON
24261f3b49SDean Nelson #define DBUG_ON(condition) BUG_ON(condition)
25261f3b49SDean Nelson #else
26261f3b49SDean Nelson #define DBUG_ON(condition)
27261f3b49SDean Nelson #endif
28261f3b49SDean Nelson
2945d9ca49SDean Nelson /*
30bc63d387SDean Nelson * Define the maximum number of partitions the system can possibly support.
31bc63d387SDean Nelson * It is based on the maximum number of hardware partitionable regions. The
32bc63d387SDean Nelson * term 'region' in this context refers to the minimum number of nodes that
33bc63d387SDean Nelson * can comprise an access protection grouping. The access protection is in
34bc63d387SDean Nelson * regards to memory, IPI and IOI.
3545d9ca49SDean Nelson *
3645d9ca49SDean Nelson * The maximum number of hardware partitionable regions is equal to the
3745d9ca49SDean Nelson * maximum number of nodes in the entire system divided by the minimum number
3845d9ca49SDean Nelson * of nodes that comprise an access protection grouping.
3945d9ca49SDean Nelson */
40bc63d387SDean Nelson #define XP_MAX_NPARTITIONS_SN2 64
41bc63d387SDean Nelson #define XP_MAX_NPARTITIONS_UV 256
4245d9ca49SDean Nelson
4345d9ca49SDean Nelson /*
4445d9ca49SDean Nelson * XPC establishes channel connections between the local partition and any
4545d9ca49SDean Nelson * other partition that is currently up. Over these channels, kernel-level
4645d9ca49SDean Nelson * `users' can communicate with their counterparts on the other partitions.
4745d9ca49SDean Nelson *
4845d9ca49SDean Nelson * If the need for additional channels arises, one can simply increase
49bc63d387SDean Nelson * XPC_MAX_NCHANNELS accordingly. If the day should come where that number
50bc63d387SDean Nelson * exceeds the absolute MAXIMUM number of channels possible (eight), then one
51bc63d387SDean Nelson * will need to make changes to the XPC code to accommodate for this.
52bc63d387SDean Nelson *
53ea57f80cSDean Nelson * The absolute maximum number of channels possible is limited to eight for
54ea57f80cSDean Nelson * performance reasons on sn2 hardware. The internal cross partition structures
55bc63d387SDean Nelson * require sixteen bytes per channel, and eight allows all of this
56bc63d387SDean Nelson * interface-shared info to fit in one 128-byte cacheline.
5745d9ca49SDean Nelson */
5845d9ca49SDean Nelson #define XPC_MEM_CHANNEL 0 /* memory channel number */
5945d9ca49SDean Nelson #define XPC_NET_CHANNEL 1 /* network channel number */
6045d9ca49SDean Nelson
61bc63d387SDean Nelson #define XPC_MAX_NCHANNELS 2 /* max #of channels allowed */
6245d9ca49SDean Nelson
63bc63d387SDean Nelson #if XPC_MAX_NCHANNELS > 8
64bc63d387SDean Nelson #error XPC_MAX_NCHANNELS exceeds absolute MAXIMUM possible.
6545d9ca49SDean Nelson #endif
6645d9ca49SDean Nelson
6745d9ca49SDean Nelson /*
68bd3e64c1SDean Nelson * Define macro, XPC_MSG_SIZE(), is provided for the user
6945d9ca49SDean Nelson * that wants to fit as many msg entries as possible in a given memory size
7045d9ca49SDean Nelson * (e.g. a memory page).
7145d9ca49SDean Nelson */
72bd3e64c1SDean Nelson #define XPC_MSG_MAX_SIZE 128
73bd3e64c1SDean Nelson #define XPC_MSG_HDR_MAX_SIZE 16
74bd3e64c1SDean Nelson #define XPC_MSG_PAYLOAD_MAX_SIZE (XPC_MSG_MAX_SIZE - XPC_MSG_HDR_MAX_SIZE)
7545d9ca49SDean Nelson
7645d9ca49SDean Nelson #define XPC_MSG_SIZE(_payload_size) \
77bd3e64c1SDean Nelson ALIGN(XPC_MSG_HDR_MAX_SIZE + (_payload_size), \
78788b66e3SMike Travis is_uv_system() ? 64 : 128)
79bd3e64c1SDean Nelson
8045d9ca49SDean Nelson
8145d9ca49SDean Nelson /*
8245d9ca49SDean Nelson * Define the return values and values passed to user's callout functions.
8345d9ca49SDean Nelson * (It is important to add new value codes at the end just preceding
8465c17b80SDean Nelson * xpUnknownReason, which must have the highest numerical value.)
8545d9ca49SDean Nelson */
8665c17b80SDean Nelson enum xp_retval {
8765c17b80SDean Nelson xpSuccess = 0,
8845d9ca49SDean Nelson
8965c17b80SDean Nelson xpNotConnected, /* 1: channel is not connected */
9065c17b80SDean Nelson xpConnected, /* 2: channel connected (opened) */
9165c17b80SDean Nelson xpRETIRED1, /* 3: (formerly xpDisconnected) */
9245d9ca49SDean Nelson
9365c17b80SDean Nelson xpMsgReceived, /* 4: message received */
9465c17b80SDean Nelson xpMsgDelivered, /* 5: message delivered and acknowledged */
9545d9ca49SDean Nelson
9665c17b80SDean Nelson xpRETIRED2, /* 6: (formerly xpTransferFailed) */
9745d9ca49SDean Nelson
9865c17b80SDean Nelson xpNoWait, /* 7: operation would require wait */
9965c17b80SDean Nelson xpRetry, /* 8: retry operation */
10065c17b80SDean Nelson xpTimeout, /* 9: timeout in xpc_allocate_msg_wait() */
10165c17b80SDean Nelson xpInterrupted, /* 10: interrupted wait */
10245d9ca49SDean Nelson
10365c17b80SDean Nelson xpUnequalMsgSizes, /* 11: message size disparity between sides */
10465c17b80SDean Nelson xpInvalidAddress, /* 12: invalid address */
10545d9ca49SDean Nelson
10665c17b80SDean Nelson xpNoMemory, /* 13: no memory available for XPC structures */
10765c17b80SDean Nelson xpLackOfResources, /* 14: insufficient resources for operation */
10865c17b80SDean Nelson xpUnregistered, /* 15: channel is not registered */
10965c17b80SDean Nelson xpAlreadyRegistered, /* 16: channel is already registered */
11045d9ca49SDean Nelson
11165c17b80SDean Nelson xpPartitionDown, /* 17: remote partition is down */
11265c17b80SDean Nelson xpNotLoaded, /* 18: XPC module is not loaded */
11365c17b80SDean Nelson xpUnloading, /* 19: this side is unloading XPC module */
11445d9ca49SDean Nelson
11565c17b80SDean Nelson xpBadMagic, /* 20: XPC MAGIC string not found */
11645d9ca49SDean Nelson
11765c17b80SDean Nelson xpReactivating, /* 21: remote partition was reactivated */
11845d9ca49SDean Nelson
11965c17b80SDean Nelson xpUnregistering, /* 22: this side is unregistering channel */
12065c17b80SDean Nelson xpOtherUnregistering, /* 23: other side is unregistering channel */
12145d9ca49SDean Nelson
12265c17b80SDean Nelson xpCloneKThread, /* 24: cloning kernel thread */
12365c17b80SDean Nelson xpCloneKThreadFailed, /* 25: cloning kernel thread failed */
12445d9ca49SDean Nelson
12565c17b80SDean Nelson xpNoHeartbeat, /* 26: remote partition has no heartbeat */
12645d9ca49SDean Nelson
12765c17b80SDean Nelson xpPioReadError, /* 27: PIO read error */
12865c17b80SDean Nelson xpPhysAddrRegFailed, /* 28: registration of phys addr range failed */
12945d9ca49SDean Nelson
13065c17b80SDean Nelson xpRETIRED3, /* 29: (formerly xpBteDirectoryError) */
13165c17b80SDean Nelson xpRETIRED4, /* 30: (formerly xpBtePoisonError) */
13265c17b80SDean Nelson xpRETIRED5, /* 31: (formerly xpBteWriteError) */
13365c17b80SDean Nelson xpRETIRED6, /* 32: (formerly xpBteAccessError) */
13465c17b80SDean Nelson xpRETIRED7, /* 33: (formerly xpBtePWriteError) */
13565c17b80SDean Nelson xpRETIRED8, /* 34: (formerly xpBtePReadError) */
13665c17b80SDean Nelson xpRETIRED9, /* 35: (formerly xpBteTimeOutError) */
13765c17b80SDean Nelson xpRETIRED10, /* 36: (formerly xpBteXtalkError) */
13865c17b80SDean Nelson xpRETIRED11, /* 37: (formerly xpBteNotAvailable) */
13965c17b80SDean Nelson xpRETIRED12, /* 38: (formerly xpBteUnmappedError) */
14045d9ca49SDean Nelson
14165c17b80SDean Nelson xpBadVersion, /* 39: bad version number */
14265c17b80SDean Nelson xpVarsNotSet, /* 40: the XPC variables are not set up */
14365c17b80SDean Nelson xpNoRsvdPageAddr, /* 41: unable to get rsvd page's phys addr */
14465c17b80SDean Nelson xpInvalidPartid, /* 42: invalid partition ID */
14565c17b80SDean Nelson xpLocalPartid, /* 43: local partition ID */
14645d9ca49SDean Nelson
14765c17b80SDean Nelson xpOtherGoingDown, /* 44: other side going down, reason unknown */
14865c17b80SDean Nelson xpSystemGoingDown, /* 45: system is going down, reason unknown */
14965c17b80SDean Nelson xpSystemHalt, /* 46: system is being halted */
15065c17b80SDean Nelson xpSystemReboot, /* 47: system is being rebooted */
15165c17b80SDean Nelson xpSystemPoweroff, /* 48: system is being powered off */
15245d9ca49SDean Nelson
15365c17b80SDean Nelson xpDisconnecting, /* 49: channel disconnecting (closing) */
15445d9ca49SDean Nelson
15565c17b80SDean Nelson xpOpenCloseError, /* 50: channel open/close protocol error */
15645d9ca49SDean Nelson
15765c17b80SDean Nelson xpDisconnected, /* 51: channel disconnected (closed) */
15845d9ca49SDean Nelson
15965c17b80SDean Nelson xpBteCopyError, /* 52: bte_copy() returned error */
160da970525SDean Nelson xpSalError, /* 53: sn SAL error */
16194bd2708SDean Nelson xpRsvdPageNotSet, /* 54: the reserved page is not set up */
16297bf1aa1SDean Nelson xpPayloadTooBig, /* 55: payload too large for message slot */
16345d9ca49SDean Nelson
16497bf1aa1SDean Nelson xpUnsupported, /* 56: unsupported functionality or resource */
165261f3b49SDean Nelson xpNeedMoreInfo, /* 57: more info is needed by SAL */
166261f3b49SDean Nelson
167a812dcc3SDean Nelson xpGruCopyError, /* 58: gru_copy_gru() returned error */
1685b8669dfSDean Nelson xpGruSendMqError, /* 59: gru send message queue related error */
169a812dcc3SDean Nelson
170bd3e64c1SDean Nelson xpBadChannelNumber, /* 60: invalid channel number */
1716c1c325dSDean Nelson xpBadMsgType, /* 61: invalid message type */
1726c1c325dSDean Nelson xpBiosError, /* 62: BIOS error */
173bd3e64c1SDean Nelson
1746c1c325dSDean Nelson xpUnknownReason /* 63: unknown reason - must be last in enum */
17545d9ca49SDean Nelson };
17645d9ca49SDean Nelson
17745d9ca49SDean Nelson /*
17865c17b80SDean Nelson * Define the callout function type used by XPC to update the user on
17965c17b80SDean Nelson * connection activity and state changes via the user function registered
18065c17b80SDean Nelson * by xpc_connect().
18145d9ca49SDean Nelson *
18245d9ca49SDean Nelson * Arguments:
18345d9ca49SDean Nelson *
18465c17b80SDean Nelson * reason - reason code.
18545d9ca49SDean Nelson * partid - partition ID associated with condition.
18645d9ca49SDean Nelson * ch_number - channel # associated with condition.
18765c17b80SDean Nelson * data - pointer to optional data.
18845d9ca49SDean Nelson * key - pointer to optional user-defined value provided as the "key"
18965c17b80SDean Nelson * argument to xpc_connect().
19045d9ca49SDean Nelson *
19165c17b80SDean Nelson * A reason code of xpConnected indicates that a connection has been
19265c17b80SDean Nelson * established to the specified partition on the specified channel. The data
19365c17b80SDean Nelson * argument indicates the max number of entries allowed in the message queue.
19445d9ca49SDean Nelson *
19565c17b80SDean Nelson * A reason code of xpMsgReceived indicates that a XPC message arrived from
19665c17b80SDean Nelson * the specified partition on the specified channel. The data argument
19765c17b80SDean Nelson * specifies the address of the message's payload. The user must call
19865c17b80SDean Nelson * xpc_received() when finished with the payload.
19945d9ca49SDean Nelson *
20065c17b80SDean Nelson * All other reason codes indicate failure. The data argmument is NULL.
20165c17b80SDean Nelson * When a failure reason code is received, one can assume that the channel
20265c17b80SDean Nelson * is not connected.
20345d9ca49SDean Nelson */
20464d032baSDean Nelson typedef void (*xpc_channel_func) (enum xp_retval reason, short partid,
20545d9ca49SDean Nelson int ch_number, void *data, void *key);
20645d9ca49SDean Nelson
20765c17b80SDean Nelson /*
20865c17b80SDean Nelson * Define the callout function type used by XPC to notify the user of
20965c17b80SDean Nelson * messages received and delivered via the user function registered by
21065c17b80SDean Nelson * xpc_send_notify().
21165c17b80SDean Nelson *
21265c17b80SDean Nelson * Arguments:
21365c17b80SDean Nelson *
21465c17b80SDean Nelson * reason - reason code.
21565c17b80SDean Nelson * partid - partition ID associated with condition.
21665c17b80SDean Nelson * ch_number - channel # associated with condition.
21765c17b80SDean Nelson * key - pointer to optional user-defined value provided as the "key"
21865c17b80SDean Nelson * argument to xpc_send_notify().
21965c17b80SDean Nelson *
22065c17b80SDean Nelson * A reason code of xpMsgDelivered indicates that the message was delivered
22165c17b80SDean Nelson * to the intended recipient and that they have acknowledged its receipt by
22265c17b80SDean Nelson * calling xpc_received().
22365c17b80SDean Nelson *
22465c17b80SDean Nelson * All other reason codes indicate failure.
225bd3e64c1SDean Nelson *
226bd3e64c1SDean Nelson * NOTE: The user defined function must be callable by an interrupt handler
227bd3e64c1SDean Nelson * and thus cannot block.
22865c17b80SDean Nelson */
22964d032baSDean Nelson typedef void (*xpc_notify_func) (enum xp_retval reason, short partid,
23045d9ca49SDean Nelson int ch_number, void *key);
23145d9ca49SDean Nelson
23245d9ca49SDean Nelson /*
23345d9ca49SDean Nelson * The following is a registration entry. There is a global array of these,
23445d9ca49SDean Nelson * one per channel. It is used to record the connection registration made
23545d9ca49SDean Nelson * by the users of XPC. As long as a registration entry exists, for any
23645d9ca49SDean Nelson * partition that comes up, XPC will attempt to establish a connection on
23745d9ca49SDean Nelson * that channel. Notification that a connection has been made will occur via
23845d9ca49SDean Nelson * the xpc_channel_func function.
23945d9ca49SDean Nelson *
24045d9ca49SDean Nelson * The 'func' field points to the function to call when aynchronous
24145d9ca49SDean Nelson * notification is required for such events as: a connection established/lost,
24245d9ca49SDean Nelson * or an incoming message received, or an error condition encountered. A
24345d9ca49SDean Nelson * non-NULL 'func' field indicates that there is an active registration for
24445d9ca49SDean Nelson * the channel.
24545d9ca49SDean Nelson */
24645d9ca49SDean Nelson struct xpc_registration {
24745d9ca49SDean Nelson struct mutex mutex;
24845d9ca49SDean Nelson xpc_channel_func func; /* function to call */
24945d9ca49SDean Nelson void *key; /* pointer to user's key */
25045d9ca49SDean Nelson u16 nentries; /* #of msg entries in local msg queue */
251bd3e64c1SDean Nelson u16 entry_size; /* message queue's message entry size */
25245d9ca49SDean Nelson u32 assigned_limit; /* limit on #of assigned kthreads */
25345d9ca49SDean Nelson u32 idle_limit; /* limit on #of idle kthreads */
25445d9ca49SDean Nelson } ____cacheline_aligned;
25545d9ca49SDean Nelson
25645d9ca49SDean Nelson #define XPC_CHANNEL_REGISTERED(_c) (xpc_registrations[_c].func != NULL)
25745d9ca49SDean Nelson
25897bf1aa1SDean Nelson /* the following are valid xpc_send() or xpc_send_notify() flags */
25945d9ca49SDean Nelson #define XPC_WAIT 0 /* wait flag */
26045d9ca49SDean Nelson #define XPC_NOWAIT 1 /* no wait flag */
26145d9ca49SDean Nelson
26245d9ca49SDean Nelson struct xpc_interface {
26345d9ca49SDean Nelson void (*connect) (int);
26445d9ca49SDean Nelson void (*disconnect) (int);
26597bf1aa1SDean Nelson enum xp_retval (*send) (short, int, u32, void *, u16);
26697bf1aa1SDean Nelson enum xp_retval (*send_notify) (short, int, u32, void *, u16,
26745d9ca49SDean Nelson xpc_notify_func, void *);
26864d032baSDean Nelson void (*received) (short, int, void *);
26964d032baSDean Nelson enum xp_retval (*partid_to_nasids) (short, void *);
27045d9ca49SDean Nelson };
27145d9ca49SDean Nelson
27245d9ca49SDean Nelson extern struct xpc_interface xpc_interface;
27345d9ca49SDean Nelson
27445d9ca49SDean Nelson extern void xpc_set_interface(void (*)(int),
27545d9ca49SDean Nelson void (*)(int),
27697bf1aa1SDean Nelson enum xp_retval (*)(short, int, u32, void *, u16),
27797bf1aa1SDean Nelson enum xp_retval (*)(short, int, u32, void *, u16,
2784a3ad2ddSDean Nelson xpc_notify_func, void *),
27964d032baSDean Nelson void (*)(short, int, void *),
28064d032baSDean Nelson enum xp_retval (*)(short, void *));
28145d9ca49SDean Nelson extern void xpc_clear_interface(void);
28245d9ca49SDean Nelson
28365c17b80SDean Nelson extern enum xp_retval xpc_connect(int, xpc_channel_func, void *, u16,
28445d9ca49SDean Nelson u16, u32, u32);
28545d9ca49SDean Nelson extern void xpc_disconnect(int);
28645d9ca49SDean Nelson
28765c17b80SDean Nelson static inline enum xp_retval
xpc_send(short partid,int ch_number,u32 flags,void * payload,u16 payload_size)28897bf1aa1SDean Nelson xpc_send(short partid, int ch_number, u32 flags, void *payload,
28997bf1aa1SDean Nelson u16 payload_size)
29045d9ca49SDean Nelson {
291234041dfSKees Cook if (!xpc_interface.send)
292234041dfSKees Cook return xpNotLoaded;
293234041dfSKees Cook
29497bf1aa1SDean Nelson return xpc_interface.send(partid, ch_number, flags, payload,
29597bf1aa1SDean Nelson payload_size);
29645d9ca49SDean Nelson }
29745d9ca49SDean Nelson
29865c17b80SDean Nelson static inline enum xp_retval
xpc_send_notify(short partid,int ch_number,u32 flags,void * payload,u16 payload_size,xpc_notify_func func,void * key)29997bf1aa1SDean Nelson xpc_send_notify(short partid, int ch_number, u32 flags, void *payload,
30097bf1aa1SDean Nelson u16 payload_size, xpc_notify_func func, void *key)
30145d9ca49SDean Nelson {
302234041dfSKees Cook if (!xpc_interface.send_notify)
303234041dfSKees Cook return xpNotLoaded;
304234041dfSKees Cook
30597bf1aa1SDean Nelson return xpc_interface.send_notify(partid, ch_number, flags, payload,
30697bf1aa1SDean Nelson payload_size, func, key);
30745d9ca49SDean Nelson }
30845d9ca49SDean Nelson
30945d9ca49SDean Nelson static inline void
xpc_received(short partid,int ch_number,void * payload)31064d032baSDean Nelson xpc_received(short partid, int ch_number, void *payload)
31145d9ca49SDean Nelson {
312234041dfSKees Cook if (xpc_interface.received)
313234041dfSKees Cook xpc_interface.received(partid, ch_number, payload);
31445d9ca49SDean Nelson }
31545d9ca49SDean Nelson
31665c17b80SDean Nelson static inline enum xp_retval
xpc_partid_to_nasids(short partid,void * nasids)31764d032baSDean Nelson xpc_partid_to_nasids(short partid, void *nasids)
31845d9ca49SDean Nelson {
319234041dfSKees Cook if (!xpc_interface.partid_to_nasids)
320234041dfSKees Cook return xpNotLoaded;
321234041dfSKees Cook
32245d9ca49SDean Nelson return xpc_interface.partid_to_nasids(partid, nasids);
32345d9ca49SDean Nelson }
32445d9ca49SDean Nelson
325bc63d387SDean Nelson extern short xp_max_npartitions;
326261f3b49SDean Nelson extern short xp_partition_id;
327261f3b49SDean Nelson extern u8 xp_region_size;
328bc63d387SDean Nelson
329a812dcc3SDean Nelson extern unsigned long (*xp_pa) (void *);
33068212893SRobin Holt extern unsigned long (*xp_socket_pa) (unsigned long);
331a812dcc3SDean Nelson extern enum xp_retval (*xp_remote_memcpy) (unsigned long, const unsigned long,
332a812dcc3SDean Nelson size_t);
333261f3b49SDean Nelson extern int (*xp_cpu_to_nasid) (int);
3346c1c325dSDean Nelson extern enum xp_retval (*xp_expand_memprotect) (unsigned long, unsigned long);
3356c1c325dSDean Nelson extern enum xp_retval (*xp_restrict_memprotect) (unsigned long, unsigned long);
336908787dbSDean Nelson
337bc63d387SDean Nelson extern struct device *xp;
338bc63d387SDean Nelson extern enum xp_retval xp_init_uv(void);
339bc63d387SDean Nelson extern void xp_exit_uv(void);
340bc63d387SDean Nelson
34145d9ca49SDean Nelson #endif /* _DRIVERS_MISC_SGIXP_XP_H */
342