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