xref: /linux/arch/s390/include/asm/diag.h (revision 3071e9b39106e1b9576584a372f446c23b258e3f)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2c6557e7fSMartin Schwidefsky /*
3c6557e7fSMartin Schwidefsky  * s390 diagnose functions
4c6557e7fSMartin Schwidefsky  *
5c6557e7fSMartin Schwidefsky  * Copyright IBM Corp. 2007
6c6557e7fSMartin Schwidefsky  * Author(s): Michael Holzheu <holzheu@de.ibm.com>
7c6557e7fSMartin Schwidefsky  */
8c6557e7fSMartin Schwidefsky 
9c6557e7fSMartin Schwidefsky #ifndef _ASM_S390_DIAG_H
10c6557e7fSMartin Schwidefsky #define _ASM_S390_DIAG_H
11c6557e7fSMartin Schwidefsky 
121b030478SJulian Wiedmann #include <linux/if_ether.h>
131ec2772eSMartin Schwidefsky #include <linux/percpu.h>
14d09a307fSHeiko Carstens #include <asm/asm-extable.h>
15fbaee746SSven Schnelle #include <asm/cio.h>
161ec2772eSMartin Schwidefsky 
171ec2772eSMartin Schwidefsky enum diag_stat_enum {
181ec2772eSMartin Schwidefsky 	DIAG_STAT_X008,
191ec2772eSMartin Schwidefsky 	DIAG_STAT_X00C,
201ec2772eSMartin Schwidefsky 	DIAG_STAT_X010,
211ec2772eSMartin Schwidefsky 	DIAG_STAT_X014,
221ec2772eSMartin Schwidefsky 	DIAG_STAT_X044,
231ec2772eSMartin Schwidefsky 	DIAG_STAT_X064,
24fbaee746SSven Schnelle 	DIAG_STAT_X08C,
251ec2772eSMartin Schwidefsky 	DIAG_STAT_X09C,
261ec2772eSMartin Schwidefsky 	DIAG_STAT_X0DC,
271ec2772eSMartin Schwidefsky 	DIAG_STAT_X204,
281ec2772eSMartin Schwidefsky 	DIAG_STAT_X210,
291ec2772eSMartin Schwidefsky 	DIAG_STAT_X224,
301ec2772eSMartin Schwidefsky 	DIAG_STAT_X250,
311ec2772eSMartin Schwidefsky 	DIAG_STAT_X258,
321b030478SJulian Wiedmann 	DIAG_STAT_X26C,
331ec2772eSMartin Schwidefsky 	DIAG_STAT_X288,
341ec2772eSMartin Schwidefsky 	DIAG_STAT_X2C4,
351ec2772eSMartin Schwidefsky 	DIAG_STAT_X2FC,
361ec2772eSMartin Schwidefsky 	DIAG_STAT_X304,
371ec2772eSMartin Schwidefsky 	DIAG_STAT_X308,
384ad78b86SCollin Walling 	DIAG_STAT_X318,
391ec2772eSMartin Schwidefsky 	DIAG_STAT_X500,
401ec2772eSMartin Schwidefsky 	NR_DIAG_STAT
411ec2772eSMartin Schwidefsky };
421ec2772eSMartin Schwidefsky 
43b5a6b71bSMartin Schwidefsky void diag_stat_inc(enum diag_stat_enum nr);
44b5a6b71bSMartin Schwidefsky void diag_stat_inc_norecursion(enum diag_stat_enum nr);
451ec2772eSMartin Schwidefsky 
46c6557e7fSMartin Schwidefsky /*
4783ace270SMichael Holzheu  * Diagnose 10: Release page range
48c6557e7fSMartin Schwidefsky  */
4983ace270SMichael Holzheu static inline void diag10_range(unsigned long start_pfn, unsigned long num_pfn)
5083ace270SMichael Holzheu {
5183ace270SMichael Holzheu 	unsigned long start_addr, end_addr;
5283ace270SMichael Holzheu 
539d6305c2SHeiko Carstens 	start_addr = pfn_to_phys(start_pfn);
549d6305c2SHeiko Carstens 	end_addr = pfn_to_phys(start_pfn + num_pfn - 1);
5583ace270SMichael Holzheu 
561ec2772eSMartin Schwidefsky 	diag_stat_inc(DIAG_STAT_X010);
5783ace270SMichael Holzheu 	asm volatile(
5883ace270SMichael Holzheu 		"0:	diag	%0,%1,0x10\n"
596c22c986SHeiko Carstens 		"1:	nopr	%%r7\n"
6083ace270SMichael Holzheu 		EX_TABLE(0b, 1b)
6183ace270SMichael Holzheu 		EX_TABLE(1b, 1b)
6283ace270SMichael Holzheu 		: : "a" (start_addr), "a" (end_addr));
6383ace270SMichael Holzheu }
64c6557e7fSMartin Schwidefsky 
65c6557e7fSMartin Schwidefsky /*
66c6557e7fSMartin Schwidefsky  * Diagnose 14: Input spool file manipulation
67c6557e7fSMartin Schwidefsky  */
68c6557e7fSMartin Schwidefsky extern int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode);
69c6557e7fSMartin Schwidefsky 
70c6557e7fSMartin Schwidefsky /*
71c6557e7fSMartin Schwidefsky  * Diagnose 210: Get information about a virtual device
72c6557e7fSMartin Schwidefsky  */
73c6557e7fSMartin Schwidefsky struct diag210 {
74c6557e7fSMartin Schwidefsky 	u16 vrdcdvno;	/* device number (input) */
75c6557e7fSMartin Schwidefsky 	u16 vrdclen;	/* data block length (input) */
76c6557e7fSMartin Schwidefsky 	u8 vrdcvcla;	/* virtual device class (output) */
77c6557e7fSMartin Schwidefsky 	u8 vrdcvtyp;	/* virtual device type (output) */
78c6557e7fSMartin Schwidefsky 	u8 vrdcvsta;	/* virtual device status (output) */
79c6557e7fSMartin Schwidefsky 	u8 vrdcvfla;	/* virtual device flags (output) */
80c6557e7fSMartin Schwidefsky 	u8 vrdcrccl;	/* real device class (output) */
81c6557e7fSMartin Schwidefsky 	u8 vrdccrty;	/* real device type (output) */
82c6557e7fSMartin Schwidefsky 	u8 vrdccrmd;	/* real device model (output) */
83c6557e7fSMartin Schwidefsky 	u8 vrdccrft;	/* real device feature (output) */
84fe5e23ddSSven Schnelle } __packed __aligned(4);
85c6557e7fSMartin Schwidefsky 
86c6557e7fSMartin Schwidefsky extern int diag210(struct diag210 *addr);
87c6557e7fSMartin Schwidefsky 
88fbaee746SSven Schnelle struct diag8c {
89fbaee746SSven Schnelle 	u8 flags;
90fbaee746SSven Schnelle 	u8 num_partitions;
91fbaee746SSven Schnelle 	u16 width;
92fbaee746SSven Schnelle 	u16 height;
93*3071e9b3SGustavo A. R. Silva 	u8 data[];
94fbaee746SSven Schnelle } __packed __aligned(4);
95fbaee746SSven Schnelle 
96fbaee746SSven Schnelle extern int diag8c(struct diag8c *out, struct ccw_dev_id *devno);
97fbaee746SSven Schnelle 
98e65f30e0SJanosch Frank /* bit is set in flags, when physical cpu info is included in diag 204 data */
99e65f30e0SJanosch Frank #define DIAG204_LPAR_PHYS_FLG 0x80
100e65f30e0SJanosch Frank #define DIAG204_LPAR_NAME_LEN 8		/* lpar name len in diag 204 data */
101e65f30e0SJanosch Frank #define DIAG204_CPU_NAME_LEN 16		/* type name len of cpus in diag224 name table */
102e65f30e0SJanosch Frank 
103e65f30e0SJanosch Frank /* diag 204 subcodes */
104e65f30e0SJanosch Frank enum diag204_sc {
105e65f30e0SJanosch Frank 	DIAG204_SUBC_STIB4 = 4,
106e65f30e0SJanosch Frank 	DIAG204_SUBC_RSI = 5,
107e65f30e0SJanosch Frank 	DIAG204_SUBC_STIB6 = 6,
108e65f30e0SJanosch Frank 	DIAG204_SUBC_STIB7 = 7
109e65f30e0SJanosch Frank };
110e65f30e0SJanosch Frank 
111e65f30e0SJanosch Frank /* The two available diag 204 data formats */
112e65f30e0SJanosch Frank enum diag204_format {
113e65f30e0SJanosch Frank 	DIAG204_INFO_SIMPLE = 0,
114e65f30e0SJanosch Frank 	DIAG204_INFO_EXT = 0x00010000
115e65f30e0SJanosch Frank };
116e65f30e0SJanosch Frank 
117a2d57b35SJanosch Frank enum diag204_cpu_flags {
118a2d57b35SJanosch Frank 	DIAG204_CPU_ONLINE = 0x20,
119a2d57b35SJanosch Frank 	DIAG204_CPU_CAPPED = 0x40,
120a2d57b35SJanosch Frank };
121a2d57b35SJanosch Frank 
122e65f30e0SJanosch Frank struct diag204_info_blk_hdr {
123e65f30e0SJanosch Frank 	__u8  npar;
124e65f30e0SJanosch Frank 	__u8  flags;
125e65f30e0SJanosch Frank 	__u16 tslice;
126e65f30e0SJanosch Frank 	__u16 phys_cpus;
127e65f30e0SJanosch Frank 	__u16 this_part;
128e65f30e0SJanosch Frank 	__u64 curtod;
129e65f30e0SJanosch Frank } __packed;
130e65f30e0SJanosch Frank 
131e65f30e0SJanosch Frank struct diag204_x_info_blk_hdr {
132e65f30e0SJanosch Frank 	__u8  npar;
133e65f30e0SJanosch Frank 	__u8  flags;
134e65f30e0SJanosch Frank 	__u16 tslice;
135e65f30e0SJanosch Frank 	__u16 phys_cpus;
136e65f30e0SJanosch Frank 	__u16 this_part;
137e65f30e0SJanosch Frank 	__u64 curtod1;
138e65f30e0SJanosch Frank 	__u64 curtod2;
139e65f30e0SJanosch Frank 	char reserved[40];
140e65f30e0SJanosch Frank } __packed;
141e65f30e0SJanosch Frank 
142e65f30e0SJanosch Frank struct diag204_part_hdr {
143e65f30e0SJanosch Frank 	__u8 pn;
144e65f30e0SJanosch Frank 	__u8 cpus;
145e65f30e0SJanosch Frank 	char reserved[6];
146e65f30e0SJanosch Frank 	char part_name[DIAG204_LPAR_NAME_LEN];
147e65f30e0SJanosch Frank } __packed;
148e65f30e0SJanosch Frank 
149e65f30e0SJanosch Frank struct diag204_x_part_hdr {
150e65f30e0SJanosch Frank 	__u8  pn;
151e65f30e0SJanosch Frank 	__u8  cpus;
152e65f30e0SJanosch Frank 	__u8  rcpus;
153e65f30e0SJanosch Frank 	__u8  pflag;
154e65f30e0SJanosch Frank 	__u32 mlu;
155e65f30e0SJanosch Frank 	char  part_name[DIAG204_LPAR_NAME_LEN];
156e65f30e0SJanosch Frank 	char  lpc_name[8];
157e65f30e0SJanosch Frank 	char  os_name[8];
158e65f30e0SJanosch Frank 	__u64 online_cs;
159e65f30e0SJanosch Frank 	__u64 online_es;
160e65f30e0SJanosch Frank 	__u8  upid;
161a2d57b35SJanosch Frank 	__u8  reserved:3;
162a2d57b35SJanosch Frank 	__u8  mtid:5;
163a2d57b35SJanosch Frank 	char  reserved1[2];
164e65f30e0SJanosch Frank 	__u32 group_mlu;
165e65f30e0SJanosch Frank 	char  group_name[8];
166a2d57b35SJanosch Frank 	char  hardware_group_name[8];
167a2d57b35SJanosch Frank 	char  reserved2[24];
168e65f30e0SJanosch Frank } __packed;
169e65f30e0SJanosch Frank 
170e65f30e0SJanosch Frank struct diag204_cpu_info {
171e65f30e0SJanosch Frank 	__u16 cpu_addr;
172e65f30e0SJanosch Frank 	char  reserved1[2];
173e65f30e0SJanosch Frank 	__u8  ctidx;
174e65f30e0SJanosch Frank 	__u8  cflag;
175e65f30e0SJanosch Frank 	__u16 weight;
176e65f30e0SJanosch Frank 	__u64 acc_time;
177e65f30e0SJanosch Frank 	__u64 lp_time;
178e65f30e0SJanosch Frank } __packed;
179e65f30e0SJanosch Frank 
180e65f30e0SJanosch Frank struct diag204_x_cpu_info {
181e65f30e0SJanosch Frank 	__u16 cpu_addr;
182e65f30e0SJanosch Frank 	char  reserved1[2];
183e65f30e0SJanosch Frank 	__u8  ctidx;
184e65f30e0SJanosch Frank 	__u8  cflag;
185e65f30e0SJanosch Frank 	__u16 weight;
186e65f30e0SJanosch Frank 	__u64 acc_time;
187e65f30e0SJanosch Frank 	__u64 lp_time;
188e65f30e0SJanosch Frank 	__u16 min_weight;
189e65f30e0SJanosch Frank 	__u16 cur_weight;
190e65f30e0SJanosch Frank 	__u16 max_weight;
191e65f30e0SJanosch Frank 	char  reseved2[2];
192e65f30e0SJanosch Frank 	__u64 online_time;
193e65f30e0SJanosch Frank 	__u64 wait_time;
194e65f30e0SJanosch Frank 	__u32 pma_weight;
195e65f30e0SJanosch Frank 	__u32 polar_weight;
196a2d57b35SJanosch Frank 	__u32 cpu_type_cap;
197a2d57b35SJanosch Frank 	__u32 group_cpu_type_cap;
198a2d57b35SJanosch Frank 	char  reserved3[32];
199e65f30e0SJanosch Frank } __packed;
200e65f30e0SJanosch Frank 
201e65f30e0SJanosch Frank struct diag204_phys_hdr {
202e65f30e0SJanosch Frank 	char reserved1[1];
203e65f30e0SJanosch Frank 	__u8 cpus;
204e65f30e0SJanosch Frank 	char reserved2[6];
205e65f30e0SJanosch Frank 	char mgm_name[8];
206e65f30e0SJanosch Frank } __packed;
207e65f30e0SJanosch Frank 
208e65f30e0SJanosch Frank struct diag204_x_phys_hdr {
209e65f30e0SJanosch Frank 	char reserved1[1];
210e65f30e0SJanosch Frank 	__u8 cpus;
211e65f30e0SJanosch Frank 	char reserved2[6];
212e65f30e0SJanosch Frank 	char mgm_name[8];
213e65f30e0SJanosch Frank 	char reserved3[80];
214e65f30e0SJanosch Frank } __packed;
215e65f30e0SJanosch Frank 
216e65f30e0SJanosch Frank struct diag204_phys_cpu {
217e65f30e0SJanosch Frank 	__u16 cpu_addr;
218e65f30e0SJanosch Frank 	char  reserved1[2];
219e65f30e0SJanosch Frank 	__u8  ctidx;
220e65f30e0SJanosch Frank 	char  reserved2[3];
221e65f30e0SJanosch Frank 	__u64 mgm_time;
222e65f30e0SJanosch Frank 	char  reserved3[8];
223e65f30e0SJanosch Frank } __packed;
224e65f30e0SJanosch Frank 
225e65f30e0SJanosch Frank struct diag204_x_phys_cpu {
226e65f30e0SJanosch Frank 	__u16 cpu_addr;
227e65f30e0SJanosch Frank 	char  reserved1[2];
228e65f30e0SJanosch Frank 	__u8  ctidx;
229a2d57b35SJanosch Frank 	char  reserved2[1];
230a2d57b35SJanosch Frank 	__u16 weight;
231e65f30e0SJanosch Frank 	__u64 mgm_time;
232e65f30e0SJanosch Frank 	char  reserved3[80];
233e65f30e0SJanosch Frank } __packed;
234e65f30e0SJanosch Frank 
23595ca2cb5SJanosch Frank struct diag204_x_part_block {
23695ca2cb5SJanosch Frank 	struct diag204_x_part_hdr hdr;
23795ca2cb5SJanosch Frank 	struct diag204_x_cpu_info cpus[];
23895ca2cb5SJanosch Frank } __packed;
23995ca2cb5SJanosch Frank 
24095ca2cb5SJanosch Frank struct diag204_x_phys_block {
24195ca2cb5SJanosch Frank 	struct diag204_x_phys_hdr hdr;
24295ca2cb5SJanosch Frank 	struct diag204_x_phys_cpu cpus[];
24395ca2cb5SJanosch Frank } __packed;
24495ca2cb5SJanosch Frank 
2451b030478SJulian Wiedmann enum diag26c_sc {
246f22237f6SJulian Wiedmann 	DIAG26C_PORT_VNIC    = 0x00000024,
2471b030478SJulian Wiedmann 	DIAG26C_MAC_SERVICES = 0x00000030
2481b030478SJulian Wiedmann };
2491b030478SJulian Wiedmann 
2501b030478SJulian Wiedmann enum diag26c_version {
251f22237f6SJulian Wiedmann 	DIAG26C_VERSION2	 = 0x00000002,	/* z/VM 5.4.0 */
252f22237f6SJulian Wiedmann 	DIAG26C_VERSION6_VM65918 = 0x00020006	/* z/VM 6.4.0 + VM65918 */
2531b030478SJulian Wiedmann };
2541b030478SJulian Wiedmann 
255f22237f6SJulian Wiedmann #define DIAG26C_VNIC_INFO	0x0002
256f22237f6SJulian Wiedmann struct diag26c_vnic_req {
257f22237f6SJulian Wiedmann 	u32	resp_buf_len;
258f22237f6SJulian Wiedmann 	u32	resp_version;
259f22237f6SJulian Wiedmann 	u16	req_format;
260f22237f6SJulian Wiedmann 	u16	vlan_id;
261f22237f6SJulian Wiedmann 	u64	sys_name;
262f22237f6SJulian Wiedmann 	u8	res[2];
263f22237f6SJulian Wiedmann 	u16	devno;
264f22237f6SJulian Wiedmann } __packed __aligned(8);
265f22237f6SJulian Wiedmann 
266f22237f6SJulian Wiedmann #define VNIC_INFO_PROT_L3	1
267f22237f6SJulian Wiedmann #define VNIC_INFO_PROT_L2	2
268f22237f6SJulian Wiedmann /* Note: this is the bare minimum, use it for uninitialized VNICs only. */
269f22237f6SJulian Wiedmann struct diag26c_vnic_resp {
270f22237f6SJulian Wiedmann 	u32	version;
271f22237f6SJulian Wiedmann 	u32	entry_cnt;
272f22237f6SJulian Wiedmann 	/* VNIC info: */
273f22237f6SJulian Wiedmann 	u32	next_entry;
274f22237f6SJulian Wiedmann 	u64	owner;
275f22237f6SJulian Wiedmann 	u16	devno;
276f22237f6SJulian Wiedmann 	u8	status;
277f22237f6SJulian Wiedmann 	u8	type;
278f22237f6SJulian Wiedmann 	u64	lan_owner;
279f22237f6SJulian Wiedmann 	u64	lan_name;
280f22237f6SJulian Wiedmann 	u64	port_name;
281f22237f6SJulian Wiedmann 	u8	port_type;
282f22237f6SJulian Wiedmann 	u8	ext_status:6;
283f22237f6SJulian Wiedmann 	u8	protocol:2;
284f22237f6SJulian Wiedmann 	u16	base_devno;
285f22237f6SJulian Wiedmann 	u32	port_num;
286f22237f6SJulian Wiedmann 	u32	ifindex;
287f22237f6SJulian Wiedmann 	u32	maxinfo;
288f22237f6SJulian Wiedmann 	u32	dev_count;
289f22237f6SJulian Wiedmann 	/* 3x device info: */
290f22237f6SJulian Wiedmann 	u8	dev_info1[28];
291f22237f6SJulian Wiedmann 	u8	dev_info2[28];
292f22237f6SJulian Wiedmann 	u8	dev_info3[28];
293f22237f6SJulian Wiedmann } __packed __aligned(8);
294f22237f6SJulian Wiedmann 
2951b030478SJulian Wiedmann #define DIAG26C_GET_MAC	0x0000
2961b030478SJulian Wiedmann struct diag26c_mac_req {
2971b030478SJulian Wiedmann 	u32	resp_buf_len;
2981b030478SJulian Wiedmann 	u32	resp_version;
2991b030478SJulian Wiedmann 	u16	op_code;
3001b030478SJulian Wiedmann 	u16	devno;
3011b030478SJulian Wiedmann 	u8	res[4];
3021b030478SJulian Wiedmann };
3031b030478SJulian Wiedmann 
3041b030478SJulian Wiedmann struct diag26c_mac_resp {
3051b030478SJulian Wiedmann 	u32	version;
3061b030478SJulian Wiedmann 	u8	mac[ETH_ALEN];
3071b030478SJulian Wiedmann 	u8	res[2];
3081b030478SJulian Wiedmann } __aligned(8);
3091b030478SJulian Wiedmann 
3104ad78b86SCollin Walling #define CPNC_LINUX		0x4
3114ad78b86SCollin Walling union diag318_info {
3124ad78b86SCollin Walling 	unsigned long val;
3134ad78b86SCollin Walling 	struct {
314a23816f3SCollin Walling 		unsigned long cpnc : 8;
315a23816f3SCollin Walling 		unsigned long cpvc : 56;
3164ad78b86SCollin Walling 	};
3174ad78b86SCollin Walling };
3184ad78b86SCollin Walling 
319e65f30e0SJanosch Frank int diag204(unsigned long subcode, unsigned long size, void *addr);
320022bd2d1SJanosch Frank int diag224(void *ptr);
3211b030478SJulian Wiedmann int diag26c(void *req, void *resp, enum diag26c_sc subcode);
322a80313ffSGerald Schaefer 
323a80313ffSGerald Schaefer struct hypfs_diag0c_entry;
324a80313ffSGerald Schaefer 
325c78d0c74SHeiko Carstens /*
326c78d0c74SHeiko Carstens  * This structure must contain only pointers/references into
327c78d0c74SHeiko Carstens  * the AMODE31 text section.
328c78d0c74SHeiko Carstens  */
329a80313ffSGerald Schaefer struct diag_ops {
330a80313ffSGerald Schaefer 	int (*diag210)(struct diag210 *addr);
331a80313ffSGerald Schaefer 	int (*diag26c)(void *req, void *resp, enum diag26c_sc subcode);
332a80313ffSGerald Schaefer 	int (*diag14)(unsigned long rx, unsigned long ry1, unsigned long subcode);
333fbaee746SSven Schnelle 	int (*diag8c)(struct diag8c *addr, struct ccw_dev_id *devno, size_t len);
334a80313ffSGerald Schaefer 	void (*diag0c)(struct hypfs_diag0c_entry *entry);
335a80313ffSGerald Schaefer 	void (*diag308_reset)(void);
336a80313ffSGerald Schaefer };
337a80313ffSGerald Schaefer 
338c78d0c74SHeiko Carstens extern struct diag_ops diag_amode31_ops;
339c78d0c74SHeiko Carstens extern struct diag210 *__diag210_tmp_amode31;
3406bda6670SAlexander Egorenkov 
341c78d0c74SHeiko Carstens int _diag210_amode31(struct diag210 *addr);
342c78d0c74SHeiko Carstens int _diag26c_amode31(void *req, void *resp, enum diag26c_sc subcode);
343c78d0c74SHeiko Carstens int _diag14_amode31(unsigned long rx, unsigned long ry1, unsigned long subcode);
344c78d0c74SHeiko Carstens void _diag0c_amode31(struct hypfs_diag0c_entry *entry);
345c78d0c74SHeiko Carstens void _diag308_reset_amode31(void);
346fbaee746SSven Schnelle int _diag8c_amode31(struct diag8c *addr, struct ccw_dev_id *devno, size_t len);
3476bda6670SAlexander Egorenkov 
348c6557e7fSMartin Schwidefsky #endif /* _ASM_S390_DIAG_H */
349