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 * 67a6d94f0SMike 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 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 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 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 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 33745d9ca49SDean Nelson extern u64 xp_nofault_PIOR_target; 33845d9ca49SDean Nelson extern int xp_nofault_PIOR(void *); 33945d9ca49SDean Nelson extern int xp_error_PIOR(void); 34045d9ca49SDean Nelson 341bc63d387SDean Nelson extern struct device *xp; 342bc63d387SDean Nelson extern enum xp_retval xp_init_uv(void); 343bc63d387SDean Nelson extern void xp_exit_uv(void); 344bc63d387SDean Nelson 34545d9ca49SDean Nelson #endif /* _DRIVERS_MISC_SGIXP_XP_H */ 346