diag.h 6.9 KB

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