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