1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 2c6557e7fSMartin Schwidefsky /* 3c6557e7fSMartin Schwidefsky * s390 diagnose functions 4c6557e7fSMartin Schwidefsky * 5c6557e7fSMartin Schwidefsky * Copyright IBM Corp. 2007 6c6557e7fSMartin Schwidefsky * Author(s): Michael Holzheu <holzheu@de.ibm.com> 7c6557e7fSMartin Schwidefsky */ 8c6557e7fSMartin Schwidefsky 9c6557e7fSMartin Schwidefsky #ifndef _ASM_S390_DIAG_H 10c6557e7fSMartin Schwidefsky #define _ASM_S390_DIAG_H 11c6557e7fSMartin Schwidefsky 121b030478SJulian Wiedmann #include <linux/if_ether.h> 131ec2772eSMartin Schwidefsky #include <linux/percpu.h> 14d09a307fSHeiko Carstens #include <asm/asm-extable.h> 15fbaee746SSven Schnelle #include <asm/cio.h> 161ec2772eSMartin Schwidefsky 171ec2772eSMartin Schwidefsky enum diag_stat_enum { 181ec2772eSMartin Schwidefsky DIAG_STAT_X008, 191ec2772eSMartin Schwidefsky DIAG_STAT_X00C, 201ec2772eSMartin Schwidefsky DIAG_STAT_X010, 211ec2772eSMartin Schwidefsky DIAG_STAT_X014, 221ec2772eSMartin Schwidefsky DIAG_STAT_X044, 231ec2772eSMartin Schwidefsky DIAG_STAT_X064, 24fbaee746SSven Schnelle DIAG_STAT_X08C, 251ec2772eSMartin Schwidefsky DIAG_STAT_X09C, 261ec2772eSMartin Schwidefsky DIAG_STAT_X0DC, 271ec2772eSMartin Schwidefsky DIAG_STAT_X204, 281ec2772eSMartin Schwidefsky DIAG_STAT_X210, 291ec2772eSMartin Schwidefsky DIAG_STAT_X224, 301ec2772eSMartin Schwidefsky DIAG_STAT_X250, 311ec2772eSMartin Schwidefsky DIAG_STAT_X258, 321b030478SJulian Wiedmann DIAG_STAT_X26C, 331ec2772eSMartin Schwidefsky DIAG_STAT_X288, 341ec2772eSMartin Schwidefsky DIAG_STAT_X2C4, 351ec2772eSMartin Schwidefsky DIAG_STAT_X2FC, 361ec2772eSMartin Schwidefsky DIAG_STAT_X304, 371ec2772eSMartin Schwidefsky DIAG_STAT_X308, 384ad78b86SCollin Walling DIAG_STAT_X318, 391ec2772eSMartin Schwidefsky DIAG_STAT_X500, 401ec2772eSMartin Schwidefsky NR_DIAG_STAT 411ec2772eSMartin Schwidefsky }; 421ec2772eSMartin Schwidefsky 43b5a6b71bSMartin Schwidefsky void diag_stat_inc(enum diag_stat_enum nr); 44b5a6b71bSMartin Schwidefsky void diag_stat_inc_norecursion(enum diag_stat_enum nr); 451ec2772eSMartin Schwidefsky 46c6557e7fSMartin Schwidefsky /* 4783ace270SMichael Holzheu * Diagnose 10: Release page range 48c6557e7fSMartin Schwidefsky */ 4983ace270SMichael Holzheu static inline void diag10_range(unsigned long start_pfn, unsigned long num_pfn) 5083ace270SMichael Holzheu { 5183ace270SMichael Holzheu unsigned long start_addr, end_addr; 5283ace270SMichael Holzheu 539d6305c2SHeiko Carstens start_addr = pfn_to_phys(start_pfn); 549d6305c2SHeiko Carstens end_addr = pfn_to_phys(start_pfn + num_pfn - 1); 5583ace270SMichael Holzheu 561ec2772eSMartin Schwidefsky diag_stat_inc(DIAG_STAT_X010); 5783ace270SMichael Holzheu asm volatile( 5883ace270SMichael Holzheu "0: diag %0,%1,0x10\n" 596c22c986SHeiko Carstens "1: nopr %%r7\n" 6083ace270SMichael Holzheu EX_TABLE(0b, 1b) 6183ace270SMichael Holzheu EX_TABLE(1b, 1b) 6283ace270SMichael Holzheu : : "a" (start_addr), "a" (end_addr)); 6383ace270SMichael Holzheu } 64c6557e7fSMartin Schwidefsky 65c6557e7fSMartin Schwidefsky /* 66c6557e7fSMartin Schwidefsky * Diagnose 14: Input spool file manipulation 67c6557e7fSMartin Schwidefsky */ 68c6557e7fSMartin Schwidefsky extern int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode); 69c6557e7fSMartin Schwidefsky 70c6557e7fSMartin Schwidefsky /* 71c6557e7fSMartin Schwidefsky * Diagnose 210: Get information about a virtual device 72c6557e7fSMartin Schwidefsky */ 73c6557e7fSMartin Schwidefsky struct diag210 { 74c6557e7fSMartin Schwidefsky u16 vrdcdvno; /* device number (input) */ 75c6557e7fSMartin Schwidefsky u16 vrdclen; /* data block length (input) */ 76c6557e7fSMartin Schwidefsky u8 vrdcvcla; /* virtual device class (output) */ 77c6557e7fSMartin Schwidefsky u8 vrdcvtyp; /* virtual device type (output) */ 78c6557e7fSMartin Schwidefsky u8 vrdcvsta; /* virtual device status (output) */ 79c6557e7fSMartin Schwidefsky u8 vrdcvfla; /* virtual device flags (output) */ 80c6557e7fSMartin Schwidefsky u8 vrdcrccl; /* real device class (output) */ 81c6557e7fSMartin Schwidefsky u8 vrdccrty; /* real device type (output) */ 82c6557e7fSMartin Schwidefsky u8 vrdccrmd; /* real device model (output) */ 83c6557e7fSMartin Schwidefsky u8 vrdccrft; /* real device feature (output) */ 84fe5e23ddSSven Schnelle } __packed __aligned(4); 85c6557e7fSMartin Schwidefsky 86c6557e7fSMartin Schwidefsky extern int diag210(struct diag210 *addr); 87c6557e7fSMartin Schwidefsky 88fbaee746SSven Schnelle struct diag8c { 89fbaee746SSven Schnelle u8 flags; 90fbaee746SSven Schnelle u8 num_partitions; 91fbaee746SSven Schnelle u16 width; 92fbaee746SSven Schnelle u16 height; 93*3071e9b3SGustavo A. R. Silva u8 data[]; 94fbaee746SSven Schnelle } __packed __aligned(4); 95fbaee746SSven Schnelle 96fbaee746SSven Schnelle extern int diag8c(struct diag8c *out, struct ccw_dev_id *devno); 97fbaee746SSven Schnelle 98e65f30e0SJanosch Frank /* bit is set in flags, when physical cpu info is included in diag 204 data */ 99e65f30e0SJanosch Frank #define DIAG204_LPAR_PHYS_FLG 0x80 100e65f30e0SJanosch Frank #define DIAG204_LPAR_NAME_LEN 8 /* lpar name len in diag 204 data */ 101e65f30e0SJanosch Frank #define DIAG204_CPU_NAME_LEN 16 /* type name len of cpus in diag224 name table */ 102e65f30e0SJanosch Frank 103e65f30e0SJanosch Frank /* diag 204 subcodes */ 104e65f30e0SJanosch Frank enum diag204_sc { 105e65f30e0SJanosch Frank DIAG204_SUBC_STIB4 = 4, 106e65f30e0SJanosch Frank DIAG204_SUBC_RSI = 5, 107e65f30e0SJanosch Frank DIAG204_SUBC_STIB6 = 6, 108e65f30e0SJanosch Frank DIAG204_SUBC_STIB7 = 7 109e65f30e0SJanosch Frank }; 110e65f30e0SJanosch Frank 111e65f30e0SJanosch Frank /* The two available diag 204 data formats */ 112e65f30e0SJanosch Frank enum diag204_format { 113e65f30e0SJanosch Frank DIAG204_INFO_SIMPLE = 0, 114e65f30e0SJanosch Frank DIAG204_INFO_EXT = 0x00010000 115e65f30e0SJanosch Frank }; 116e65f30e0SJanosch Frank 117a2d57b35SJanosch Frank enum diag204_cpu_flags { 118a2d57b35SJanosch Frank DIAG204_CPU_ONLINE = 0x20, 119a2d57b35SJanosch Frank DIAG204_CPU_CAPPED = 0x40, 120a2d57b35SJanosch Frank }; 121a2d57b35SJanosch Frank 122e65f30e0SJanosch Frank struct diag204_info_blk_hdr { 123e65f30e0SJanosch Frank __u8 npar; 124e65f30e0SJanosch Frank __u8 flags; 125e65f30e0SJanosch Frank __u16 tslice; 126e65f30e0SJanosch Frank __u16 phys_cpus; 127e65f30e0SJanosch Frank __u16 this_part; 128e65f30e0SJanosch Frank __u64 curtod; 129e65f30e0SJanosch Frank } __packed; 130e65f30e0SJanosch Frank 131e65f30e0SJanosch Frank struct diag204_x_info_blk_hdr { 132e65f30e0SJanosch Frank __u8 npar; 133e65f30e0SJanosch Frank __u8 flags; 134e65f30e0SJanosch Frank __u16 tslice; 135e65f30e0SJanosch Frank __u16 phys_cpus; 136e65f30e0SJanosch Frank __u16 this_part; 137e65f30e0SJanosch Frank __u64 curtod1; 138e65f30e0SJanosch Frank __u64 curtod2; 139e65f30e0SJanosch Frank char reserved[40]; 140e65f30e0SJanosch Frank } __packed; 141e65f30e0SJanosch Frank 142e65f30e0SJanosch Frank struct diag204_part_hdr { 143e65f30e0SJanosch Frank __u8 pn; 144e65f30e0SJanosch Frank __u8 cpus; 145e65f30e0SJanosch Frank char reserved[6]; 146e65f30e0SJanosch Frank char part_name[DIAG204_LPAR_NAME_LEN]; 147e65f30e0SJanosch Frank } __packed; 148e65f30e0SJanosch Frank 149e65f30e0SJanosch Frank struct diag204_x_part_hdr { 150e65f30e0SJanosch Frank __u8 pn; 151e65f30e0SJanosch Frank __u8 cpus; 152e65f30e0SJanosch Frank __u8 rcpus; 153e65f30e0SJanosch Frank __u8 pflag; 154e65f30e0SJanosch Frank __u32 mlu; 155e65f30e0SJanosch Frank char part_name[DIAG204_LPAR_NAME_LEN]; 156e65f30e0SJanosch Frank char lpc_name[8]; 157e65f30e0SJanosch Frank char os_name[8]; 158e65f30e0SJanosch Frank __u64 online_cs; 159e65f30e0SJanosch Frank __u64 online_es; 160e65f30e0SJanosch Frank __u8 upid; 161a2d57b35SJanosch Frank __u8 reserved:3; 162a2d57b35SJanosch Frank __u8 mtid:5; 163a2d57b35SJanosch Frank char reserved1[2]; 164e65f30e0SJanosch Frank __u32 group_mlu; 165e65f30e0SJanosch Frank char group_name[8]; 166a2d57b35SJanosch Frank char hardware_group_name[8]; 167a2d57b35SJanosch Frank char reserved2[24]; 168e65f30e0SJanosch Frank } __packed; 169e65f30e0SJanosch Frank 170e65f30e0SJanosch Frank struct diag204_cpu_info { 171e65f30e0SJanosch Frank __u16 cpu_addr; 172e65f30e0SJanosch Frank char reserved1[2]; 173e65f30e0SJanosch Frank __u8 ctidx; 174e65f30e0SJanosch Frank __u8 cflag; 175e65f30e0SJanosch Frank __u16 weight; 176e65f30e0SJanosch Frank __u64 acc_time; 177e65f30e0SJanosch Frank __u64 lp_time; 178e65f30e0SJanosch Frank } __packed; 179e65f30e0SJanosch Frank 180e65f30e0SJanosch Frank struct diag204_x_cpu_info { 181e65f30e0SJanosch Frank __u16 cpu_addr; 182e65f30e0SJanosch Frank char reserved1[2]; 183e65f30e0SJanosch Frank __u8 ctidx; 184e65f30e0SJanosch Frank __u8 cflag; 185e65f30e0SJanosch Frank __u16 weight; 186e65f30e0SJanosch Frank __u64 acc_time; 187e65f30e0SJanosch Frank __u64 lp_time; 188e65f30e0SJanosch Frank __u16 min_weight; 189e65f30e0SJanosch Frank __u16 cur_weight; 190e65f30e0SJanosch Frank __u16 max_weight; 191e65f30e0SJanosch Frank char reseved2[2]; 192e65f30e0SJanosch Frank __u64 online_time; 193e65f30e0SJanosch Frank __u64 wait_time; 194e65f30e0SJanosch Frank __u32 pma_weight; 195e65f30e0SJanosch Frank __u32 polar_weight; 196a2d57b35SJanosch Frank __u32 cpu_type_cap; 197a2d57b35SJanosch Frank __u32 group_cpu_type_cap; 198a2d57b35SJanosch Frank char reserved3[32]; 199e65f30e0SJanosch Frank } __packed; 200e65f30e0SJanosch Frank 201e65f30e0SJanosch Frank struct diag204_phys_hdr { 202e65f30e0SJanosch Frank char reserved1[1]; 203e65f30e0SJanosch Frank __u8 cpus; 204e65f30e0SJanosch Frank char reserved2[6]; 205e65f30e0SJanosch Frank char mgm_name[8]; 206e65f30e0SJanosch Frank } __packed; 207e65f30e0SJanosch Frank 208e65f30e0SJanosch Frank struct diag204_x_phys_hdr { 209e65f30e0SJanosch Frank char reserved1[1]; 210e65f30e0SJanosch Frank __u8 cpus; 211e65f30e0SJanosch Frank char reserved2[6]; 212e65f30e0SJanosch Frank char mgm_name[8]; 213e65f30e0SJanosch Frank char reserved3[80]; 214e65f30e0SJanosch Frank } __packed; 215e65f30e0SJanosch Frank 216e65f30e0SJanosch Frank struct diag204_phys_cpu { 217e65f30e0SJanosch Frank __u16 cpu_addr; 218e65f30e0SJanosch Frank char reserved1[2]; 219e65f30e0SJanosch Frank __u8 ctidx; 220e65f30e0SJanosch Frank char reserved2[3]; 221e65f30e0SJanosch Frank __u64 mgm_time; 222e65f30e0SJanosch Frank char reserved3[8]; 223e65f30e0SJanosch Frank } __packed; 224e65f30e0SJanosch Frank 225e65f30e0SJanosch Frank struct diag204_x_phys_cpu { 226e65f30e0SJanosch Frank __u16 cpu_addr; 227e65f30e0SJanosch Frank char reserved1[2]; 228e65f30e0SJanosch Frank __u8 ctidx; 229a2d57b35SJanosch Frank char reserved2[1]; 230a2d57b35SJanosch Frank __u16 weight; 231e65f30e0SJanosch Frank __u64 mgm_time; 232e65f30e0SJanosch Frank char reserved3[80]; 233e65f30e0SJanosch Frank } __packed; 234e65f30e0SJanosch Frank 23595ca2cb5SJanosch Frank struct diag204_x_part_block { 23695ca2cb5SJanosch Frank struct diag204_x_part_hdr hdr; 23795ca2cb5SJanosch Frank struct diag204_x_cpu_info cpus[]; 23895ca2cb5SJanosch Frank } __packed; 23995ca2cb5SJanosch Frank 24095ca2cb5SJanosch Frank struct diag204_x_phys_block { 24195ca2cb5SJanosch Frank struct diag204_x_phys_hdr hdr; 24295ca2cb5SJanosch Frank struct diag204_x_phys_cpu cpus[]; 24395ca2cb5SJanosch Frank } __packed; 24495ca2cb5SJanosch Frank 2451b030478SJulian Wiedmann enum diag26c_sc { 246f22237f6SJulian Wiedmann DIAG26C_PORT_VNIC = 0x00000024, 2471b030478SJulian Wiedmann DIAG26C_MAC_SERVICES = 0x00000030 2481b030478SJulian Wiedmann }; 2491b030478SJulian Wiedmann 2501b030478SJulian Wiedmann enum diag26c_version { 251f22237f6SJulian Wiedmann DIAG26C_VERSION2 = 0x00000002, /* z/VM 5.4.0 */ 252f22237f6SJulian Wiedmann DIAG26C_VERSION6_VM65918 = 0x00020006 /* z/VM 6.4.0 + VM65918 */ 2531b030478SJulian Wiedmann }; 2541b030478SJulian Wiedmann 255f22237f6SJulian Wiedmann #define DIAG26C_VNIC_INFO 0x0002 256f22237f6SJulian Wiedmann struct diag26c_vnic_req { 257f22237f6SJulian Wiedmann u32 resp_buf_len; 258f22237f6SJulian Wiedmann u32 resp_version; 259f22237f6SJulian Wiedmann u16 req_format; 260f22237f6SJulian Wiedmann u16 vlan_id; 261f22237f6SJulian Wiedmann u64 sys_name; 262f22237f6SJulian Wiedmann u8 res[2]; 263f22237f6SJulian Wiedmann u16 devno; 264f22237f6SJulian Wiedmann } __packed __aligned(8); 265f22237f6SJulian Wiedmann 266f22237f6SJulian Wiedmann #define VNIC_INFO_PROT_L3 1 267f22237f6SJulian Wiedmann #define VNIC_INFO_PROT_L2 2 268f22237f6SJulian Wiedmann /* Note: this is the bare minimum, use it for uninitialized VNICs only. */ 269f22237f6SJulian Wiedmann struct diag26c_vnic_resp { 270f22237f6SJulian Wiedmann u32 version; 271f22237f6SJulian Wiedmann u32 entry_cnt; 272f22237f6SJulian Wiedmann /* VNIC info: */ 273f22237f6SJulian Wiedmann u32 next_entry; 274f22237f6SJulian Wiedmann u64 owner; 275f22237f6SJulian Wiedmann u16 devno; 276f22237f6SJulian Wiedmann u8 status; 277f22237f6SJulian Wiedmann u8 type; 278f22237f6SJulian Wiedmann u64 lan_owner; 279f22237f6SJulian Wiedmann u64 lan_name; 280f22237f6SJulian Wiedmann u64 port_name; 281f22237f6SJulian Wiedmann u8 port_type; 282f22237f6SJulian Wiedmann u8 ext_status:6; 283f22237f6SJulian Wiedmann u8 protocol:2; 284f22237f6SJulian Wiedmann u16 base_devno; 285f22237f6SJulian Wiedmann u32 port_num; 286f22237f6SJulian Wiedmann u32 ifindex; 287f22237f6SJulian Wiedmann u32 maxinfo; 288f22237f6SJulian Wiedmann u32 dev_count; 289f22237f6SJulian Wiedmann /* 3x device info: */ 290f22237f6SJulian Wiedmann u8 dev_info1[28]; 291f22237f6SJulian Wiedmann u8 dev_info2[28]; 292f22237f6SJulian Wiedmann u8 dev_info3[28]; 293f22237f6SJulian Wiedmann } __packed __aligned(8); 294f22237f6SJulian Wiedmann 2951b030478SJulian Wiedmann #define DIAG26C_GET_MAC 0x0000 2961b030478SJulian Wiedmann struct diag26c_mac_req { 2971b030478SJulian Wiedmann u32 resp_buf_len; 2981b030478SJulian Wiedmann u32 resp_version; 2991b030478SJulian Wiedmann u16 op_code; 3001b030478SJulian Wiedmann u16 devno; 3011b030478SJulian Wiedmann u8 res[4]; 3021b030478SJulian Wiedmann }; 3031b030478SJulian Wiedmann 3041b030478SJulian Wiedmann struct diag26c_mac_resp { 3051b030478SJulian Wiedmann u32 version; 3061b030478SJulian Wiedmann u8 mac[ETH_ALEN]; 3071b030478SJulian Wiedmann u8 res[2]; 3081b030478SJulian Wiedmann } __aligned(8); 3091b030478SJulian Wiedmann 3104ad78b86SCollin Walling #define CPNC_LINUX 0x4 3114ad78b86SCollin Walling union diag318_info { 3124ad78b86SCollin Walling unsigned long val; 3134ad78b86SCollin Walling struct { 314a23816f3SCollin Walling unsigned long cpnc : 8; 315a23816f3SCollin Walling unsigned long cpvc : 56; 3164ad78b86SCollin Walling }; 3174ad78b86SCollin Walling }; 3184ad78b86SCollin Walling 319e65f30e0SJanosch Frank int diag204(unsigned long subcode, unsigned long size, void *addr); 320022bd2d1SJanosch Frank int diag224(void *ptr); 3211b030478SJulian Wiedmann int diag26c(void *req, void *resp, enum diag26c_sc subcode); 322a80313ffSGerald Schaefer 323a80313ffSGerald Schaefer struct hypfs_diag0c_entry; 324a80313ffSGerald Schaefer 325c78d0c74SHeiko Carstens /* 326c78d0c74SHeiko Carstens * This structure must contain only pointers/references into 327c78d0c74SHeiko Carstens * the AMODE31 text section. 328c78d0c74SHeiko Carstens */ 329a80313ffSGerald Schaefer struct diag_ops { 330a80313ffSGerald Schaefer int (*diag210)(struct diag210 *addr); 331a80313ffSGerald Schaefer int (*diag26c)(void *req, void *resp, enum diag26c_sc subcode); 332a80313ffSGerald Schaefer int (*diag14)(unsigned long rx, unsigned long ry1, unsigned long subcode); 333fbaee746SSven Schnelle int (*diag8c)(struct diag8c *addr, struct ccw_dev_id *devno, size_t len); 334a80313ffSGerald Schaefer void (*diag0c)(struct hypfs_diag0c_entry *entry); 335a80313ffSGerald Schaefer void (*diag308_reset)(void); 336a80313ffSGerald Schaefer }; 337a80313ffSGerald Schaefer 338c78d0c74SHeiko Carstens extern struct diag_ops diag_amode31_ops; 339c78d0c74SHeiko Carstens extern struct diag210 *__diag210_tmp_amode31; 3406bda6670SAlexander Egorenkov 341c78d0c74SHeiko Carstens int _diag210_amode31(struct diag210 *addr); 342c78d0c74SHeiko Carstens int _diag26c_amode31(void *req, void *resp, enum diag26c_sc subcode); 343c78d0c74SHeiko Carstens int _diag14_amode31(unsigned long rx, unsigned long ry1, unsigned long subcode); 344c78d0c74SHeiko Carstens void _diag0c_amode31(struct hypfs_diag0c_entry *entry); 345c78d0c74SHeiko Carstens void _diag308_reset_amode31(void); 346fbaee746SSven Schnelle int _diag8c_amode31(struct diag8c *addr, struct ccw_dev_id *devno, size_t len); 3476bda6670SAlexander Egorenkov 348c6557e7fSMartin Schwidefsky #endif /* _ASM_S390_DIAG_H */ 349