xref: /linux/arch/s390/include/asm/diag.h (revision 375d5d57545f53d2bc3e15ada0e9da360fc68bea)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * s390 diagnose functions
4  *
5  * Copyright IBM Corp. 2007
6  * Author(s): Michael Holzheu <holzheu@de.ibm.com>
7  */
8 
9 #ifndef _ASM_S390_DIAG_H
10 #define _ASM_S390_DIAG_H
11 
12 #include <linux/if_ether.h>
13 #include <linux/percpu.h>
14 #include <asm/asm-extable.h>
15 #include <asm/sclp.h>
16 #include <asm/cio.h>
17 
18 enum diag_stat_enum {
19 	DIAG_STAT_X008,
20 	DIAG_STAT_X00C,
21 	DIAG_STAT_X010,
22 	DIAG_STAT_X014,
23 	DIAG_STAT_X044,
24 	DIAG_STAT_X064,
25 	DIAG_STAT_X08C,
26 	DIAG_STAT_X09C,
27 	DIAG_STAT_X0DC,
28 	DIAG_STAT_X204,
29 	DIAG_STAT_X210,
30 	DIAG_STAT_X224,
31 	DIAG_STAT_X250,
32 	DIAG_STAT_X258,
33 	DIAG_STAT_X26C,
34 	DIAG_STAT_X288,
35 	DIAG_STAT_X2C4,
36 	DIAG_STAT_X2FC,
37 	DIAG_STAT_X304,
38 	DIAG_STAT_X308,
39 	DIAG_STAT_X310,
40 	DIAG_STAT_X318,
41 	DIAG_STAT_X320,
42 	DIAG_STAT_X324,
43 	DIAG_STAT_X49C,
44 	DIAG_STAT_X500,
45 	NR_DIAG_STAT
46 };
47 
48 void diag_stat_inc(enum diag_stat_enum nr);
49 void diag_stat_inc_norecursion(enum diag_stat_enum nr);
50 
51 struct hypfs_diag0c_entry;
52 
53 /*
54  * Diagnose 0c: Pseudo Timer
55  */
56 void diag0c(struct hypfs_diag0c_entry *data);
57 
58 /*
59  * Diagnose 10: Release page range
60  */
diag10_range(unsigned long start_pfn,unsigned long num_pfn)61 static inline void diag10_range(unsigned long start_pfn, unsigned long num_pfn)
62 {
63 	unsigned long start_addr, end_addr;
64 
65 	start_addr = pfn_to_phys(start_pfn);
66 	end_addr = pfn_to_phys(start_pfn + num_pfn - 1);
67 
68 	diag_stat_inc(DIAG_STAT_X010);
69 	asm_inline volatile(
70 		"0:	diag	%0,%1,0x10\n"
71 		"1:\n"
72 		EX_TABLE_INSN(0b, 1b)
73 		: : "a" (start_addr), "a" (end_addr));
74 }
75 
76 /*
77  * Diagnose 14: Input spool file manipulation
78  */
79 extern int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode);
80 
81 /*
82  * Diagnose 210: Get information about a virtual device
83  */
84 struct diag210 {
85 	u16 vrdcdvno;	/* device number (input) */
86 	u16 vrdclen;	/* data block length (input) */
87 	u8 vrdcvcla;	/* virtual device class (output) */
88 	u8 vrdcvtyp;	/* virtual device type (output) */
89 	u8 vrdcvsta;	/* virtual device status (output) */
90 	u8 vrdcvfla;	/* virtual device flags (output) */
91 	u8 vrdcrccl;	/* real device class (output) */
92 	u8 vrdccrty;	/* real device type (output) */
93 	u8 vrdccrmd;	/* real device model (output) */
94 	u8 vrdccrft;	/* real device feature (output) */
95 } __packed __aligned(4);
96 
97 extern int diag210(struct diag210 *addr);
98 
99 struct diag8c {
100 	u8 flags;
101 	u8 num_partitions;
102 	u16 width;
103 	u16 height;
104 	u8 data[];
105 } __packed __aligned(4);
106 
107 extern int diag8c(struct diag8c *out, struct ccw_dev_id *devno);
108 
109 /* bit is set in flags, when physical cpu info is included in diag 204 data */
110 #define DIAG204_LPAR_PHYS_FLG 0x80
111 #define DIAG204_LPAR_NAME_LEN 8		/* lpar name len in diag 204 data */
112 #define DIAG204_CPU_NAME_LEN 16		/* type name len of cpus in diag224 name table */
113 
114 /* diag 204 subcodes */
115 enum diag204_sc {
116 	DIAG204_SUBC_STIB4 = 4,
117 	DIAG204_SUBC_RSI = 5,
118 	DIAG204_SUBC_STIB6 = 6,
119 	DIAG204_SUBC_STIB7 = 7
120 };
121 
122 #define DIAG204_SUBCODE_MASK 0xffff
123 #define DIAG204_BIF_BIT 0x80000000
124 #define DIAG204_BUSY_WAIT (HZ / 10)
125 
126 /* The two available diag 204 data formats */
127 enum diag204_format {
128 	DIAG204_INFO_SIMPLE = 0,
129 	DIAG204_INFO_EXT = 0x00010000
130 };
131 
132 enum diag204_cpu_flags {
133 	DIAG204_CPU_ONLINE = 0x20,
134 	DIAG204_CPU_CAPPED = 0x40,
135 };
136 
137 struct diag204_info_blk_hdr {
138 	__u8  npar;
139 	__u8  flags;
140 	__u16 tslice;
141 	__u16 phys_cpus;
142 	__u16 this_part;
143 	__u64 curtod;
144 } __packed;
145 
146 struct diag204_x_info_blk_hdr {
147 	__u8  npar;
148 	__u8  flags;
149 	__u16 tslice;
150 	__u16 phys_cpus;
151 	__u16 this_part;
152 	__u64 curtod1;
153 	__u64 curtod2;
154 	char reserved[40];
155 } __packed;
156 
157 struct diag204_part_hdr {
158 	__u8 pn;
159 	__u8 cpus;
160 	char reserved[6];
161 	char part_name[DIAG204_LPAR_NAME_LEN];
162 } __packed;
163 
164 struct diag204_x_part_hdr {
165 	__u8  pn;
166 	__u8  cpus;
167 	__u8  rcpus;
168 	__u8  pflag;
169 	__u32 mlu;
170 	char  part_name[DIAG204_LPAR_NAME_LEN];
171 	char  lpc_name[8];
172 	char  os_name[8];
173 	__u64 online_cs;
174 	__u64 online_es;
175 	__u8  upid;
176 	__u8  reserved:3;
177 	__u8  mtid:5;
178 	char  reserved1[2];
179 	__u32 group_mlu;
180 	char  group_name[8];
181 	char  hardware_group_name[8];
182 	char  reserved2[24];
183 } __packed;
184 
185 struct diag204_cpu_info {
186 	__u16 cpu_addr;
187 	char  reserved1[2];
188 	__u8  ctidx;
189 	__u8  cflag;
190 	__u16 weight;
191 	__u64 acc_time;
192 	__u64 lp_time;
193 } __packed;
194 
195 struct diag204_x_cpu_info {
196 	__u16 cpu_addr;
197 	char  reserved1[2];
198 	__u8  ctidx;
199 	__u8  cflag;
200 	__u16 weight;
201 	__u64 acc_time;
202 	__u64 lp_time;
203 	__u16 min_weight;
204 	__u16 cur_weight;
205 	__u16 max_weight;
206 	char  reseved2[2];
207 	__u64 online_time;
208 	__u64 wait_time;
209 	__u32 pma_weight;
210 	__u32 polar_weight;
211 	__u32 cpu_type_cap;
212 	__u32 group_cpu_type_cap;
213 	char  reserved3[32];
214 } __packed;
215 
216 struct diag204_phys_hdr {
217 	char reserved1[1];
218 	__u8 cpus;
219 	char reserved2[6];
220 	char mgm_name[8];
221 } __packed;
222 
223 struct diag204_x_phys_hdr {
224 	char reserved1[1];
225 	__u8 cpus;
226 	char reserved2[6];
227 	char mgm_name[8];
228 	char reserved3[80];
229 } __packed;
230 
231 struct diag204_phys_cpu {
232 	__u16 cpu_addr;
233 	char  reserved1[2];
234 	__u8  ctidx;
235 	char  reserved2[3];
236 	__u64 mgm_time;
237 	char  reserved3[8];
238 } __packed;
239 
240 struct diag204_x_phys_cpu {
241 	__u16 cpu_addr;
242 	char  reserved1[2];
243 	__u8  ctidx;
244 	char  reserved2[1];
245 	__u16 weight;
246 	__u64 mgm_time;
247 	char  reserved3[80];
248 } __packed;
249 
250 struct diag204_x_part_block {
251 	struct diag204_x_part_hdr hdr;
252 	struct diag204_x_cpu_info cpus[];
253 } __packed;
254 
255 struct diag204_x_phys_block {
256 	struct diag204_x_phys_hdr hdr;
257 	struct diag204_x_phys_cpu cpus[];
258 } __packed;
259 
260 enum diag26c_sc {
261 	DIAG26C_PORT_VNIC    = 0x00000024,
262 	DIAG26C_MAC_SERVICES = 0x00000030
263 };
264 
265 enum diag26c_version {
266 	DIAG26C_VERSION2	 = 0x00000002,	/* z/VM 5.4.0 */
267 	DIAG26C_VERSION6_VM65918 = 0x00020006	/* z/VM 6.4.0 + VM65918 */
268 };
269 
270 #define DIAG26C_VNIC_INFO	0x0002
271 struct diag26c_vnic_req {
272 	u32	resp_buf_len;
273 	u32	resp_version;
274 	u16	req_format;
275 	u16	vlan_id;
276 	u64	sys_name;
277 	u8	res[2];
278 	u16	devno;
279 } __packed __aligned(8);
280 
281 #define VNIC_INFO_PROT_L3	1
282 #define VNIC_INFO_PROT_L2	2
283 /* Note: this is the bare minimum, use it for uninitialized VNICs only. */
284 struct diag26c_vnic_resp {
285 	u32	version;
286 	u32	entry_cnt;
287 	/* VNIC info: */
288 	u32	next_entry;
289 	u64	owner;
290 	u16	devno;
291 	u8	status;
292 	u8	type;
293 	u64	lan_owner;
294 	u64	lan_name;
295 	u64	port_name;
296 	u8	port_type;
297 	u8	ext_status:6;
298 	u8	protocol:2;
299 	u16	base_devno;
300 	u32	port_num;
301 	u32	ifindex;
302 	u32	maxinfo;
303 	u32	dev_count;
304 	/* 3x device info: */
305 	u8	dev_info1[28];
306 	u8	dev_info2[28];
307 	u8	dev_info3[28];
308 } __packed __aligned(8);
309 
310 #define DIAG26C_GET_MAC	0x0000
311 struct diag26c_mac_req {
312 	u32	resp_buf_len;
313 	u32	resp_version;
314 	u16	op_code;
315 	u16	devno;
316 	u8	res[4];
317 };
318 
319 struct diag26c_mac_resp {
320 	u32	version;
321 	u8	mac[ETH_ALEN];
322 	u8	res[2];
323 } __aligned(8);
324 
325 #define CPNC_LINUX		0x4
326 union diag318_info {
327 	unsigned long val;
328 	struct {
329 		unsigned long cpnc : 8;
330 		unsigned long cpvc : 56;
331 	};
332 };
333 
diag204_has_bif(void)334 static inline bool diag204_has_bif(void)
335 {
336 	return sclp.has_diag204_bif;
337 }
338 
339 int diag204(unsigned long subcode, unsigned long size, void *addr);
340 int diag224(void *ptr);
341 int diag26c(void *req, void *resp, enum diag26c_sc subcode);
342 
343 struct hypfs_diag0c_entry;
344 
345 /*
346  * This structure must contain only pointers/references into
347  * the AMODE31 text section.
348  */
349 struct diag_ops {
350 	int (*diag210)(struct diag210 *addr);
351 	int (*diag26c)(unsigned long rx, unsigned long rx1, enum diag26c_sc subcode);
352 	int (*diag14)(unsigned long rx, unsigned long ry1, unsigned long subcode);
353 	int (*diag8c)(struct diag8c *addr, struct ccw_dev_id *devno, size_t len);
354 	void (*diag0c)(unsigned long rx);
355 	void (*diag308_reset)(void);
356 };
357 
358 extern struct diag_ops diag_amode31_ops;
359 extern struct diag210 *__diag210_tmp_amode31;
360 
361 int _diag210_amode31(struct diag210 *addr);
362 int _diag26c_amode31(unsigned long rx, unsigned long rx1, enum diag26c_sc subcode);
363 int _diag14_amode31(unsigned long rx, unsigned long ry1, unsigned long subcode);
364 void _diag0c_amode31(unsigned long rx);
365 void _diag308_reset_amode31(void);
366 int _diag8c_amode31(struct diag8c *addr, struct ccw_dev_id *devno, size_t len);
367 
368 /* diag 49c subcodes */
369 enum diag49c_sc {
370 	DIAG49C_SUBC_ACK = 0,
371 	DIAG49C_SUBC_REG = 1
372 };
373 
374 int diag49c(unsigned long subcode);
375 
376 #endif /* _ASM_S390_DIAG_H */
377