xref: /openbmc/linux/arch/s390/include/asm/diag.h (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
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_X320,
40  	DIAG_STAT_X500,
41  	NR_DIAG_STAT
42  };
43  
44  void diag_stat_inc(enum diag_stat_enum nr);
45  void diag_stat_inc_norecursion(enum diag_stat_enum nr);
46  
47  /*
48   * Diagnose 10: Release page range
49   */
diag10_range(unsigned long start_pfn,unsigned long num_pfn)50  static 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   */
69  extern int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode);
70  
71  /*
72   * Diagnose 210: Get information about a virtual device
73   */
74  struct 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  
87  extern int diag210(struct diag210 *addr);
88  
89  struct diag8c {
90  	u8 flags;
91  	u8 num_partitions;
92  	u16 width;
93  	u16 height;
94  	u8 data[];
95  } __packed __aligned(4);
96  
97  extern 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 */
105  enum 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 */
115  enum diag204_format {
116  	DIAG204_INFO_SIMPLE = 0,
117  	DIAG204_INFO_EXT = 0x00010000
118  };
119  
120  enum diag204_cpu_flags {
121  	DIAG204_CPU_ONLINE = 0x20,
122  	DIAG204_CPU_CAPPED = 0x40,
123  };
124  
125  struct 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  
134  struct 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  
145  struct diag204_part_hdr {
146  	__u8 pn;
147  	__u8 cpus;
148  	char reserved[6];
149  	char part_name[DIAG204_LPAR_NAME_LEN];
150  } __packed;
151  
152  struct 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  
173  struct 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  
183  struct 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  
204  struct diag204_phys_hdr {
205  	char reserved1[1];
206  	__u8 cpus;
207  	char reserved2[6];
208  	char mgm_name[8];
209  } __packed;
210  
211  struct 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  
219  struct 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  
228  struct 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  
238  struct diag204_x_part_block {
239  	struct diag204_x_part_hdr hdr;
240  	struct diag204_x_cpu_info cpus[];
241  } __packed;
242  
243  struct diag204_x_phys_block {
244  	struct diag204_x_phys_hdr hdr;
245  	struct diag204_x_phys_cpu cpus[];
246  } __packed;
247  
248  enum diag26c_sc {
249  	DIAG26C_PORT_VNIC    = 0x00000024,
250  	DIAG26C_MAC_SERVICES = 0x00000030
251  };
252  
253  enum 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
259  struct 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. */
272  struct 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
299  struct 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  
307  struct diag26c_mac_resp {
308  	u32	version;
309  	u8	mac[ETH_ALEN];
310  	u8	res[2];
311  } __aligned(8);
312  
313  #define CPNC_LINUX		0x4
314  union diag318_info {
315  	unsigned long val;
316  	struct {
317  		unsigned long cpnc : 8;
318  		unsigned long cpvc : 56;
319  	};
320  };
321  
322  int diag204(unsigned long subcode, unsigned long size, void *addr);
323  int diag224(void *ptr);
324  int diag26c(void *req, void *resp, enum diag26c_sc subcode);
325  
326  struct hypfs_diag0c_entry;
327  
328  /*
329   * This structure must contain only pointers/references into
330   * the AMODE31 text section.
331   */
332  struct 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  
341  extern struct diag_ops diag_amode31_ops;
342  extern struct diag210 *__diag210_tmp_amode31;
343  
344  int _diag210_amode31(struct diag210 *addr);
345  int _diag26c_amode31(void *req, void *resp, enum diag26c_sc subcode);
346  int _diag14_amode31(unsigned long rx, unsigned long ry1, unsigned long subcode);
347  void _diag0c_amode31(struct hypfs_diag0c_entry *entry);
348  void _diag308_reset_amode31(void);
349  int _diag8c_amode31(struct diag8c *addr, struct ccw_dev_id *devno, size_t len);
350  
351  #endif /* _ASM_S390_DIAG_H */
352