📄 xpc.h
字号:
/* * 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-2006 Silicon Graphics, Inc. All Rights Reserved. *//* * Cross Partition Communication (XPC) structures and macros. */#ifndef _ASM_IA64_SN_XPC_H#define _ASM_IA64_SN_XPC_H#include <linux/config.h>#include <linux/interrupt.h>#include <linux/sysctl.h>#include <linux/device.h>#include <linux/mutex.h>#include <linux/completion.h>#include <asm/pgtable.h>#include <asm/processor.h>#include <asm/sn/bte.h>#include <asm/sn/clksupport.h>#include <asm/sn/addrs.h>#include <asm/sn/mspec.h>#include <asm/sn/shub_mmr.h>#include <asm/sn/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)/* * The next macros define word or bit representations for given * C-brick nasid in either the SAL provided bit array representing * nasids in the partition/machine or the AMO_t array used for * inter-partition initiation communications. * * For SN2 machines, C-Bricks are alway even numbered NASIDs. As * such, some space will be saved by insisting that nasid information * passed from SAL always be packed for C-Bricks and the * cross-partition interrupts use the same packing scheme. */#define XPC_NASID_W_INDEX(_n) (((_n) / 64) / 2)#define XPC_NASID_B_INDEX(_n) (((_n) / 2) & (64 - 1))#define XPC_NASID_IN_ARRAY(_n, _p) ((_p)[XPC_NASID_W_INDEX(_n)] & \ (1UL << XPC_NASID_B_INDEX(_n)))#define XPC_NASID_FROM_W_B(_w, _b) (((_w) * 64 + (_b)) * 2)#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 cacheline of the reserved page contains 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, partid, and 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. 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 'nasids_size'. (Local partition's * mask pointers are xpc_part_nasids and xpc_mach_nasids.) * * vars * vars part * * 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. * (Local partition's vars pointers are xpc_vars and xpc_vars_part.) * * Note: Until vars_pa is set, the partition XPC code has not been initialized. */struct xpc_rsvd_page { u64 SAL_signature; /* SAL: unique signature */ u64 SAL_version; /* SAL: version */ u8 partid; /* SAL: partition ID */ u8 version; u8 pad1[6]; /* align to next u64 in cacheline */ volatile u64 vars_pa; struct timespec stamp; /* time when reserved page was setup by XPC */ u64 pad2[9]; /* align to last u64 in cacheline */ u64 nasids_size; /* SAL: size of each nasid mask in bytes */};#define XPC_RP_VERSION _XPC_VERSION(1,1) /* version 1.1 of the reserved page */#define XPC_SUPPORTS_RP_STAMP(_version) \ (_version >= _XPC_VERSION(1,1))/* * compare stamps - the return value is: * * < 0, if stamp1 < stamp2 * = 0, if stamp1 == stamp2 * > 0, if stamp1 > stamp2 */static inline intxpc_compare_stamps(struct timespec *stamp1, struct timespec *stamp2){ int ret; if ((ret = stamp1->tv_sec - stamp2->tv_sec) == 0) { ret = stamp1->tv_nsec - stamp2->tv_nsec; } return ret;}/* * Define the structures by which XPC variables can be exported to other * partitions. (There are two: struct xpc_vars and struct xpc_vars_part) *//* * The following structure describes the partition generic variables * needed by other partitions in order to properly initialize. * * struct xpc_vars version number also applies to struct xpc_vars_part. * Changes to either structure and/or related functionality should be * reflected by incrementing either the major or minor version numbers * of struct xpc_vars. */struct xpc_vars { u8 version; u64 heartbeat; u64 heartbeating_to_mask; u64 heartbeat_offline; /* if 0, heartbeat should be changing */ int act_nasid; int act_phys_cpuid; u64 vars_part_pa; u64 amos_page_pa; /* paddr of page of AMOs from MSPEC driver */ AMO_t *amos_page; /* vaddr of page of AMOs from MSPEC driver */};#define XPC_V_VERSION _XPC_VERSION(3,1) /* version 3.1 of the cross vars */#define XPC_SUPPORTS_DISENGAGE_REQUEST(_version) \ (_version >= _XPC_VERSION(3,1))static inline intxpc_hb_allowed(partid_t partid, struct xpc_vars *vars){ return ((vars->heartbeating_to_mask & (1UL << partid)) != 0);}static inline voidxpc_allow_hb(partid_t partid, struct xpc_vars *vars){ u64 old_mask, new_mask; do { old_mask = vars->heartbeating_to_mask; new_mask = (old_mask | (1UL << partid)); } while (cmpxchg(&vars->heartbeating_to_mask, old_mask, new_mask) != old_mask);}static inline voidxpc_disallow_hb(partid_t partid, struct xpc_vars *vars){ u64 old_mask, new_mask; do { old_mask = vars->heartbeating_to_mask; new_mask = (old_mask & ~(1UL << partid)); } while (cmpxchg(&vars->heartbeating_to_mask, old_mask, new_mask) != old_mask);}/* * The AMOs page consists of a number of AMO variables which are divided into * four groups, The first two groups are used to identify an IRQ's sender. * These two groups consist of 64 and 128 AMO variables respectively. The last * two groups, consisting of just one AMO variable each, are used to identify * the remote partitions that are currently engaged (from the viewpoint of * the XPC running on the remote partition). */#define XPC_NOTIFY_IRQ_AMOS 0#define XPC_ACTIVATE_IRQ_AMOS (XPC_NOTIFY_IRQ_AMOS + XP_MAX_PARTITIONS)#define XPC_ENGAGED_PARTITIONS_AMO (XPC_ACTIVATE_IRQ_AMOS + XP_NASID_MASK_WORDS)#define XPC_DISENGAGE_REQUEST_AMO (XPC_ENGAGED_PARTITIONS_AMO + 1)/* * The following structure describes the per partition specific variables. * * An array of these structures, one per partition, will be defined. As a * partition becomes active XPC will copy the array entry corresponding to * itself from that partition. It is desirable that the size of this * structure evenly divide into a cacheline, such that none of the entries * in this array crosses a cacheline boundary. As it is now, each entry * occupies half a cacheline. */struct xpc_vars_part { volatile u64 magic; u64 openclose_args_pa; /* physical address of open and close args */ u64 GPs_pa; /* physical address of Get/Put values */ u64 IPI_amo_pa; /* physical address of IPI AMO_t structure */ int IPI_nasid; /* nasid of where to send IPIs */ int IPI_phys_cpuid; /* physical CPU ID of where to send IPIs */ u8 nchannels; /* #of defined channels supported */ u8 reserved[23]; /* pad to a full 64 bytes */};/* * The vars_part MAGIC numbers play a part in the first contact protocol. * * MAGIC1 indicates that the per partition specific variables for a remote * partition have been initialized by this partition. * * MAGIC2 indicates that this partition has pulled the remote partititions * per partition variables that pertain to this partition. */#define XPC_VP_MAGIC1 0x0053524156435058L /* 'XPCVARS\0'L (little endian) */#define XPC_VP_MAGIC2 0x0073726176435058L /* 'XPCvars\0'L (little endian) *//* the reserved page sizes and offsets */#define XPC_RP_HEADER_SIZE L1_CACHE_ALIGN(sizeof(struct xpc_rsvd_page))#define XPC_RP_VARS_SIZE L1_CACHE_ALIGN(sizeof(struct xpc_vars))#define XPC_RP_PART_NASIDS(_rp) (u64 *) ((u8 *) _rp + XPC_RP_HEADER_SIZE)#define XPC_RP_MACH_NASIDS(_rp) (XPC_RP_PART_NASIDS(_rp) + xp_nasid_mask_words)#define XPC_RP_VARS(_rp) ((struct xpc_vars *) XPC_RP_MACH_NASIDS(_rp) + xp_nasid_mask_words)#define XPC_RP_VARS_PART(_rp) (struct xpc_vars_part *) ((u8 *) XPC_RP_VARS(rp) + XPC_RP_VARS_SIZE)/* * 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 Get/Put value pair (pointers) used with a message queue. */struct xpc_gp { volatile s64 get; /* Get value */ volatile s64 put; /* Put value */};#define XPC_GP_SIZE \ L1_CACHE_ALIGN(sizeof(struct xpc_gp) * XPC_NCHANNELS)/* * 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 msg_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 */ u64 local_msgqueue_pa; /* physical address of local message queue */};#define XPC_OPENCLOSE_ARGS_SIZE \ L1_CACHE_ALIGN(sizeof(struct xpc_openclose_args) * XPC_NCHANNELS)/* struct xpc_msg flags */#define XPC_M_DONE 0x01 /* msg has been received/consumed */#define XPC_M_READY 0x02 /* msg is ready to be sent */#define XPC_M_INTERRUPT 0x04 /* send interrupt when msg consumed */#define XPC_MSG_ADDRESS(_payload) \ ((struct xpc_msg *)((u8 *)(_payload) - XPC_MSG_PAYLOAD_OFFSET))/* * Defines notify entry. * * This is used to notify a message's sender that their message was received * and consumed by the intended recipient. */struct xpc_notify { volatile u8 type; /* type of notification */ /* the following two fields are only used if type == XPC_N_CALL */ xpc_notify_func func; /* user's notify function */ void *key; /* pointer to user's key */};/* struct xpc_notify type of notification */#define XPC_N_CALL 0x01 /* notify function provided by user *//* * 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. * * Each of these structures manages two message queues (circular buffers). * They are allocated at the time a channel connection is made. One of * these message queues (local_msgqueue) holds the locally created messages * that are destined for the remote partition. The other of these message * queues (remote_msgqueue) is a locally cached copy of the remote partition's * own local_msgqueue. * * The following is a description of the Get/Put pointers used to manage these * two message queues. Consider the local_msgqueue to be on one partition * and the remote_msgqueue to be its cached copy on another partition. A * description of what each of the lettered areas contains is included. * * * local_msgqueue remote_msgqueue * * |/////////| |/////////| * w_remote_GP.get --> +---------+ |/////////| * | F | |/////////| * remote_GP.get --> +---------+ +---------+ <-- local_GP->get * | | | | * | | | E | * | | | | * | | +---------+ <-- w_local_GP.get * | B | |/////////| * | | |////D////| * | | |/////////| * | | +---------+ <-- w_remote_GP.put * | | |////C////| * local_GP->put --> +---------+ +---------+ <-- remote_GP.put * | | |/////////| * | A | |/////////| * | | |/////////| * w_local_GP.put --> +---------+ |/////////| * |/////////| |/////////| * * * ( remote_GP.[get|put] are cached copies of the remote * partition's local_GP->[get|put], and thus their values can * lag behind their counterparts on the remote partition. ) * * * A - Messages that have been allocated, but have not yet been sent to the * remote partition. * * B - Messages that have been sent, but have not yet been acknowledged by the * remote partition as having been received. * * C - Area that needs to be prepared for the copying of sent messages, by * the clearing of the message flags of any previously received messages. * * D - Area into which sent messages are to be copied from the remote * partition's local_msgqueue and then delivered to their intended * recipients. [ To allow for a multi-message copy, another pointer * (next_msg_to_pull) has been added to keep track of the next message * number needing to be copied (pulled). It chases after w_remote_GP.put. * Any messages lying between w_local_GP.get and next_msg_to_pull have * been copied and are ready to be delivered. ] *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -