cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sclp.h (11699B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2/*
      3 * Copyright IBM Corp. 1999,2012
      4 *
      5 * Author(s): Martin Peschke <mpeschke@de.ibm.com>
      6 *	      Martin Schwidefsky <schwidefsky@de.ibm.com>
      7 */
      8
      9#ifndef __SCLP_H__
     10#define __SCLP_H__
     11
     12#include <linux/types.h>
     13#include <linux/list.h>
     14#include <asm/asm-extable.h>
     15#include <asm/sclp.h>
     16#include <asm/ebcdic.h>
     17
     18/* maximum number of pages concerning our own memory management */
     19#define MAX_KMEM_PAGES (sizeof(unsigned long) << 3)
     20#define SCLP_CONSOLE_PAGES	6
     21
     22#define SCLP_EVTYP_MASK(T) (1UL << (sizeof(sccb_mask_t) * BITS_PER_BYTE - (T)))
     23
     24#define EVTYP_OPCMD		0x01
     25#define EVTYP_MSG		0x02
     26#define EVTYP_CONFMGMDATA	0x04
     27#define EVTYP_DIAG_TEST		0x07
     28#define EVTYP_STATECHANGE	0x08
     29#define EVTYP_PMSGCMD		0x09
     30#define EVTYP_ASYNC		0x0A
     31#define EVTYP_CTLPROGIDENT	0x0B
     32#define EVTYP_STORE_DATA	0x0C
     33#define EVTYP_ERRNOTIFY		0x18
     34#define EVTYP_VT220MSG		0x1A
     35#define EVTYP_SDIAS		0x1C
     36#define EVTYP_SIGQUIESCE	0x1D
     37#define EVTYP_OCF		0x1E
     38
     39#define EVTYP_OPCMD_MASK	SCLP_EVTYP_MASK(EVTYP_OPCMD)
     40#define EVTYP_MSG_MASK		SCLP_EVTYP_MASK(EVTYP_MSG)
     41#define EVTYP_CONFMGMDATA_MASK	SCLP_EVTYP_MASK(EVTYP_CONFMGMDATA)
     42#define EVTYP_DIAG_TEST_MASK	SCLP_EVTYP_MASK(EVTYP_DIAG_TEST)
     43#define EVTYP_STATECHANGE_MASK	SCLP_EVTYP_MASK(EVTYP_STATECHANGE)
     44#define EVTYP_PMSGCMD_MASK	SCLP_EVTYP_MASK(EVTYP_PMSGCMD)
     45#define EVTYP_ASYNC_MASK	SCLP_EVTYP_MASK(EVTYP_ASYNC)
     46#define EVTYP_CTLPROGIDENT_MASK	SCLP_EVTYP_MASK(EVTYP_CTLPROGIDENT)
     47#define EVTYP_STORE_DATA_MASK	SCLP_EVTYP_MASK(EVTYP_STORE_DATA)
     48#define EVTYP_ERRNOTIFY_MASK	SCLP_EVTYP_MASK(EVTYP_ERRNOTIFY)
     49#define EVTYP_VT220MSG_MASK	SCLP_EVTYP_MASK(EVTYP_VT220MSG)
     50#define EVTYP_SDIAS_MASK	SCLP_EVTYP_MASK(EVTYP_SDIAS)
     51#define EVTYP_SIGQUIESCE_MASK	SCLP_EVTYP_MASK(EVTYP_SIGQUIESCE)
     52#define EVTYP_OCF_MASK		SCLP_EVTYP_MASK(EVTYP_OCF)
     53
     54#define GNRLMSGFLGS_DOM		0x8000
     55#define GNRLMSGFLGS_SNDALRM	0x4000
     56#define GNRLMSGFLGS_HOLDMSG	0x2000
     57
     58#define LNTPFLGS_CNTLTEXT	0x8000
     59#define LNTPFLGS_LABELTEXT	0x4000
     60#define LNTPFLGS_DATATEXT	0x2000
     61#define LNTPFLGS_ENDTEXT	0x1000
     62#define LNTPFLGS_PROMPTTEXT	0x0800
     63
     64typedef unsigned int sclp_cmdw_t;
     65
     66#define SCLP_CMDW_READ_CPU_INFO		0x00010001
     67#define SCLP_CMDW_READ_SCP_INFO		0x00020001
     68#define SCLP_CMDW_READ_STORAGE_INFO	0x00040001
     69#define SCLP_CMDW_READ_SCP_INFO_FORCED	0x00120001
     70#define SCLP_CMDW_READ_EVENT_DATA	0x00770005
     71#define SCLP_CMDW_WRITE_EVENT_DATA	0x00760005
     72#define SCLP_CMDW_WRITE_EVENT_MASK	0x00780005
     73
     74#define GDS_ID_MDSMU		0x1310
     75#define GDS_ID_MDSROUTEINFO	0x1311
     76#define GDS_ID_AGUNWRKCORR	0x1549
     77#define GDS_ID_SNACONDREPORT	0x1532
     78#define GDS_ID_CPMSU		0x1212
     79#define GDS_ID_ROUTTARGINSTR	0x154D
     80#define GDS_ID_OPREQ		0x8070
     81#define GDS_ID_TEXTCMD		0x1320
     82
     83#define GDS_KEY_SELFDEFTEXTMSG	0x31
     84
     85typedef u64 sccb_mask_t;
     86
     87struct sccb_header {
     88	u16	length;
     89	u8	function_code;
     90	u8	control_mask[3];
     91	u16	response_code;
     92} __attribute__((packed));
     93
     94struct init_sccb {
     95	struct sccb_header header;
     96	u16 _reserved;
     97	u16 mask_length;
     98	u8 masks[4 * 1021];	/* variable length */
     99	/*
    100	 * u8 receive_mask[mask_length];
    101	 * u8 send_mask[mask_length];
    102	 * u8 sclp_receive_mask[mask_length];
    103	 * u8 sclp_send_mask[mask_length];
    104	 */
    105} __attribute__((packed));
    106
    107#define SCLP_MASK_SIZE_COMPAT 4
    108
    109static inline sccb_mask_t sccb_get_mask(u8 *masks, size_t len, int i)
    110{
    111	sccb_mask_t res = 0;
    112
    113	memcpy(&res, masks + i * len, min(sizeof(res), len));
    114	return res;
    115}
    116
    117static inline void sccb_set_mask(u8 *masks, size_t len, int i, sccb_mask_t val)
    118{
    119	memset(masks + i * len, 0, len);
    120	memcpy(masks + i * len, &val, min(sizeof(val), len));
    121}
    122
    123#define sccb_get_generic_mask(sccb, i)					\
    124({									\
    125	__typeof__(sccb) __sccb = sccb;					\
    126									\
    127	sccb_get_mask(__sccb->masks, __sccb->mask_length, i);		\
    128})
    129#define sccb_get_recv_mask(sccb)	sccb_get_generic_mask(sccb, 0)
    130#define sccb_get_send_mask(sccb)	sccb_get_generic_mask(sccb, 1)
    131#define sccb_get_sclp_recv_mask(sccb)	sccb_get_generic_mask(sccb, 2)
    132#define sccb_get_sclp_send_mask(sccb)	sccb_get_generic_mask(sccb, 3)
    133
    134#define sccb_set_generic_mask(sccb, i, val)				\
    135({									\
    136	__typeof__(sccb) __sccb = sccb;					\
    137									\
    138	sccb_set_mask(__sccb->masks, __sccb->mask_length, i, val);	\
    139})
    140#define sccb_set_recv_mask(sccb, val)	    sccb_set_generic_mask(sccb, 0, val)
    141#define sccb_set_send_mask(sccb, val)	    sccb_set_generic_mask(sccb, 1, val)
    142#define sccb_set_sclp_recv_mask(sccb, val)  sccb_set_generic_mask(sccb, 2, val)
    143#define sccb_set_sclp_send_mask(sccb, val)  sccb_set_generic_mask(sccb, 3, val)
    144
    145struct read_cpu_info_sccb {
    146	struct	sccb_header header;
    147	u16	nr_configured;
    148	u16	offset_configured;
    149	u16	nr_standby;
    150	u16	offset_standby;
    151	/*
    152	 * Without ext sccb, struct size is PAGE_SIZE.
    153	 * With ext sccb, struct size is EXT_SCCB_READ_CPU.
    154	 */
    155	u8	reserved[];
    156} __attribute__((packed, aligned(PAGE_SIZE)));
    157
    158struct read_info_sccb {
    159	struct	sccb_header header;	/* 0-7 */
    160	u16	rnmax;			/* 8-9 */
    161	u8	rnsize;			/* 10 */
    162	u8	_pad_11[16 - 11];	/* 11-15 */
    163	u16	ncpurl;			/* 16-17 */
    164	u16	cpuoff;			/* 18-19 */
    165	u8	_pad_20[24 - 20];	/* 20-23 */
    166	u8	loadparm[8];		/* 24-31 */
    167	u8	_pad_32[42 - 32];	/* 32-41 */
    168	u8	fac42;			/* 42 */
    169	u8	fac43;			/* 43 */
    170	u8	_pad_44[48 - 44];	/* 44-47 */
    171	u64	facilities;		/* 48-55 */
    172	u8	_pad_56[66 - 56];	/* 56-65 */
    173	u8	fac66;			/* 66 */
    174	u8	_pad_67[76 - 67];	/* 67-83 */
    175	u32	ibc;			/* 76-79 */
    176	u8	_pad80[84 - 80];	/* 80-83 */
    177	u8	fac84;			/* 84 */
    178	u8	fac85;			/* 85 */
    179	u8	_pad_86[91 - 86];	/* 86-90 */
    180	u8	fac91;			/* 91 */
    181	u8	_pad_92[98 - 92];	/* 92-97 */
    182	u8	fac98;			/* 98 */
    183	u8	hamaxpow;		/* 99 */
    184	u32	rnsize2;		/* 100-103 */
    185	u64	rnmax2;			/* 104-111 */
    186	u32	hsa_size;		/* 112-115 */
    187	u8	fac116;			/* 116 */
    188	u8	fac117;			/* 117 */
    189	u8	fac118;			/* 118 */
    190	u8	fac119;			/* 119 */
    191	u16	hcpua;			/* 120-121 */
    192	u8	_pad_122[124 - 122];	/* 122-123 */
    193	u32	hmfai;			/* 124-127 */
    194	u8	_pad_128[134 - 128];	/* 128-133 */
    195	u8	byte_134;			/* 134 */
    196	u8	cpudirq;		/* 135 */
    197	u16	cbl;			/* 136-137 */
    198	u8	_pad_138[EXT_SCCB_READ_SCP - 138];
    199} __packed __aligned(PAGE_SIZE);
    200
    201struct read_storage_sccb {
    202	struct sccb_header header;
    203	u16 max_id;
    204	u16 assigned;
    205	u16 standby;
    206	u16 :16;
    207	u32 entries[0];
    208} __packed;
    209
    210static inline void sclp_fill_core_info(struct sclp_core_info *info,
    211				       struct read_cpu_info_sccb *sccb)
    212{
    213	char *page = (char *) sccb;
    214
    215	memset(info, 0, sizeof(*info));
    216	info->configured = sccb->nr_configured;
    217	info->standby = sccb->nr_standby;
    218	info->combined = sccb->nr_configured + sccb->nr_standby;
    219	memcpy(&info->core, page + sccb->offset_configured,
    220	       info->combined * sizeof(struct sclp_core_entry));
    221}
    222
    223#define SCLP_HAS_CHP_INFO	(sclp.facilities & 0x8000000000000000ULL)
    224#define SCLP_HAS_CHP_RECONFIG	(sclp.facilities & 0x2000000000000000ULL)
    225#define SCLP_HAS_CPU_INFO	(sclp.facilities & 0x0800000000000000ULL)
    226#define SCLP_HAS_CPU_RECONFIG	(sclp.facilities & 0x0400000000000000ULL)
    227#define SCLP_HAS_PCI_RECONFIG	(sclp.facilities & 0x0000000040000000ULL)
    228#define SCLP_HAS_AP_RECONFIG	(sclp.facilities & 0x0000000100000000ULL)
    229
    230struct gds_subvector {
    231	u8	length;
    232	u8	key;
    233} __attribute__((packed));
    234
    235struct gds_vector {
    236	u16	length;
    237	u16	gds_id;
    238} __attribute__((packed));
    239
    240struct evbuf_header {
    241	u16	length;
    242	u8	type;
    243	u8	flags;
    244	u16	_reserved;
    245} __attribute__((packed));
    246
    247struct sclp_req {
    248	struct list_head list;		/* list_head for request queueing. */
    249	sclp_cmdw_t command;		/* sclp command to execute */
    250	void	*sccb;			/* pointer to the sccb to execute */
    251	char	status;			/* status of this request */
    252	int     start_count;		/* number of SVCs done for this req */
    253	/* Callback that is called after reaching final status. */
    254	void (*callback)(struct sclp_req *, void *data);
    255	void *callback_data;
    256	int queue_timeout;		/* request queue timeout (sec), set by
    257					   caller of sclp_add_request(), if
    258					   needed */
    259	/* Internal fields */
    260	unsigned long queue_expires;	/* request queue timeout (jiffies) */
    261};
    262
    263#define SCLP_REQ_FILLED	  0x00	/* request is ready to be processed */
    264#define SCLP_REQ_QUEUED	  0x01	/* request is queued to be processed */
    265#define SCLP_REQ_RUNNING  0x02	/* request is currently running */
    266#define SCLP_REQ_DONE	  0x03	/* request is completed successfully */
    267#define SCLP_REQ_FAILED	  0x05	/* request is finally failed */
    268#define SCLP_REQ_QUEUED_TIMEOUT 0x06	/* request on queue timed out */
    269
    270#define SCLP_QUEUE_INTERVAL 5	/* timeout interval for request queue */
    271
    272/* function pointers that a high level driver has to use for registration */
    273/* of some routines it wants to be called from the low level driver */
    274struct sclp_register {
    275	struct list_head list;
    276	/* User wants to receive: */
    277	sccb_mask_t receive_mask;
    278	/* User wants to send: */
    279	sccb_mask_t send_mask;
    280	/* H/W can receive: */
    281	sccb_mask_t sclp_receive_mask;
    282	/* H/W can send: */
    283	sccb_mask_t sclp_send_mask;
    284	/* called if event type availability changes */
    285	void (*state_change_fn)(struct sclp_register *);
    286	/* called for events in cp_receive_mask/sclp_receive_mask */
    287	void (*receiver_fn)(struct evbuf_header *);
    288};
    289
    290/* externals from sclp.c */
    291int sclp_add_request(struct sclp_req *req);
    292void sclp_sync_wait(void);
    293int sclp_register(struct sclp_register *reg);
    294void sclp_unregister(struct sclp_register *reg);
    295int sclp_remove_processed(struct sccb_header *sccb);
    296int sclp_deactivate(void);
    297int sclp_reactivate(void);
    298int sclp_sync_request(sclp_cmdw_t command, void *sccb);
    299int sclp_sync_request_timeout(sclp_cmdw_t command, void *sccb, int timeout);
    300int sclp_sdias_init(void);
    301
    302enum {
    303	sclp_init_state_uninitialized,
    304	sclp_init_state_initializing,
    305	sclp_init_state_initialized
    306};
    307
    308extern int sclp_init_state;
    309extern int sclp_console_pages;
    310extern int sclp_console_drop;
    311extern unsigned long sclp_console_full;
    312extern bool sclp_mask_compat_mode;
    313
    314void sclp_early_wait_irq(void);
    315int sclp_early_cmd(sclp_cmdw_t cmd, void *sccb);
    316unsigned int sclp_early_con_check_linemode(struct init_sccb *sccb);
    317unsigned int sclp_early_con_check_vt220(struct init_sccb *sccb);
    318int sclp_early_set_event_mask(struct init_sccb *sccb,
    319			      sccb_mask_t receive_mask,
    320			      sccb_mask_t send_mask);
    321struct read_info_sccb * __init sclp_early_get_info(void);
    322
    323/* useful inlines */
    324
    325/* Perform service call. Return 0 on success, non-zero otherwise. */
    326static inline int sclp_service_call(sclp_cmdw_t command, void *sccb)
    327{
    328	int cc = 4; /* Initialize for program check handling */
    329
    330	asm volatile(
    331		"0:	.insn	rre,0xb2200000,%1,%2\n"	 /* servc %1,%2 */
    332		"1:	ipm	%0\n"
    333		"	srl	%0,28\n"
    334		"2:\n"
    335		EX_TABLE(0b, 2b)
    336		EX_TABLE(1b, 2b)
    337		: "+&d" (cc) : "d" (command), "a" (__pa(sccb))
    338		: "cc", "memory");
    339	if (cc == 4)
    340		return -EINVAL;
    341	if (cc == 3)
    342		return -EIO;
    343	if (cc == 2)
    344		return -EBUSY;
    345	return 0;
    346}
    347
    348/* VM uses EBCDIC 037, LPAR+native(SE+HMC) use EBCDIC 500 */
    349/* translate single character from ASCII to EBCDIC */
    350static inline unsigned char
    351sclp_ascebc(unsigned char ch)
    352{
    353	return (MACHINE_IS_VM) ? _ascebc[ch] : _ascebc_500[ch];
    354}
    355
    356/* translate string from EBCDIC to ASCII */
    357static inline void
    358sclp_ebcasc_str(char *str, int nr)
    359{
    360	(MACHINE_IS_VM) ? EBCASC(str, nr) : EBCASC_500(str, nr);
    361}
    362
    363/* translate string from ASCII to EBCDIC */
    364static inline void
    365sclp_ascebc_str(char *str, int nr)
    366{
    367	(MACHINE_IS_VM) ? ASCEBC(str, nr) : ASCEBC_500(str, nr);
    368}
    369
    370static inline struct gds_vector *
    371sclp_find_gds_vector(void *start, void *end, u16 id)
    372{
    373	struct gds_vector *v;
    374
    375	for (v = start; (void *) v < end; v = (void *) v + v->length)
    376		if (v->gds_id == id)
    377			return v;
    378	return NULL;
    379}
    380
    381static inline struct gds_subvector *
    382sclp_find_gds_subvector(void *start, void *end, u8 key)
    383{
    384	struct gds_subvector *sv;
    385
    386	for (sv = start; (void *) sv < end; sv = (void *) sv + sv->length)
    387		if (sv->key == key)
    388			return sv;
    389	return NULL;
    390}
    391
    392#endif	 /* __SCLP_H__ */