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