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