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