mic_debugfs.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. /*
  2. * Intel MIC Platform Software Stack (MPSS)
  3. *
  4. * Copyright(c) 2013 Intel Corporation.
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License, version 2, as
  8. * published by the Free Software Foundation.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * General Public License for more details.
  14. *
  15. * The full GNU General Public License is included in this distribution in
  16. * the file called "COPYING".
  17. *
  18. * Intel MIC Host driver.
  19. *
  20. */
  21. #include <linux/debugfs.h>
  22. #include <linux/pci.h>
  23. #include <linux/seq_file.h>
  24. #include <linux/mic_common.h>
  25. #include "../common/mic_device.h"
  26. #include "mic_device.h"
  27. #include "mic_smpt.h"
  28. #include "mic_virtio.h"
  29. /* Debugfs parent dir */
  30. static struct dentry *mic_dbg;
  31. /**
  32. * mic_log_buf_show - Display MIC kernel log buffer.
  33. *
  34. * log_buf addr/len is read from System.map by user space
  35. * and populated in sysfs entries.
  36. */
  37. static int mic_log_buf_show(struct seq_file *s, void *unused)
  38. {
  39. void __iomem *log_buf_va;
  40. int __iomem *log_buf_len_va;
  41. struct mic_device *mdev = s->private;
  42. void *kva;
  43. int size;
  44. unsigned long aper_offset;
  45. if (!mdev || !mdev->log_buf_addr || !mdev->log_buf_len)
  46. goto done;
  47. /*
  48. * Card kernel will never be relocated and any kernel text/data mapping
  49. * can be translated to phys address by subtracting __START_KERNEL_map.
  50. */
  51. aper_offset = (unsigned long)mdev->log_buf_len - __START_KERNEL_map;
  52. log_buf_len_va = mdev->aper.va + aper_offset;
  53. aper_offset = (unsigned long)mdev->log_buf_addr - __START_KERNEL_map;
  54. log_buf_va = mdev->aper.va + aper_offset;
  55. size = ioread32(log_buf_len_va);
  56. kva = kmalloc(size, GFP_KERNEL);
  57. if (!kva)
  58. goto done;
  59. mutex_lock(&mdev->mic_mutex);
  60. memcpy_fromio(kva, log_buf_va, size);
  61. switch (mdev->state) {
  62. case MIC_ONLINE:
  63. /* Fall through */
  64. case MIC_SHUTTING_DOWN:
  65. seq_write(s, kva, size);
  66. break;
  67. default:
  68. break;
  69. }
  70. mutex_unlock(&mdev->mic_mutex);
  71. kfree(kva);
  72. done:
  73. return 0;
  74. }
  75. static int mic_log_buf_open(struct inode *inode, struct file *file)
  76. {
  77. return single_open(file, mic_log_buf_show, inode->i_private);
  78. }
  79. static int mic_log_buf_release(struct inode *inode, struct file *file)
  80. {
  81. return single_release(inode, file);
  82. }
  83. static const struct file_operations log_buf_ops = {
  84. .owner = THIS_MODULE,
  85. .open = mic_log_buf_open,
  86. .read = seq_read,
  87. .llseek = seq_lseek,
  88. .release = mic_log_buf_release
  89. };
  90. static int mic_smpt_show(struct seq_file *s, void *pos)
  91. {
  92. int i;
  93. struct mic_device *mdev = s->private;
  94. unsigned long flags;
  95. seq_printf(s, "MIC %-2d |%-10s| %-14s %-10s\n",
  96. mdev->id, "SMPT entry", "SW DMA addr", "RefCount");
  97. seq_puts(s, "====================================================\n");
  98. if (mdev->smpt) {
  99. struct mic_smpt_info *smpt_info = mdev->smpt;
  100. spin_lock_irqsave(&smpt_info->smpt_lock, flags);
  101. for (i = 0; i < smpt_info->info.num_reg; i++) {
  102. seq_printf(s, "%9s|%-10d| %-#14llx %-10lld\n",
  103. " ", i, smpt_info->entry[i].dma_addr,
  104. smpt_info->entry[i].ref_count);
  105. }
  106. spin_unlock_irqrestore(&smpt_info->smpt_lock, flags);
  107. }
  108. seq_puts(s, "====================================================\n");
  109. return 0;
  110. }
  111. static int mic_smpt_debug_open(struct inode *inode, struct file *file)
  112. {
  113. return single_open(file, mic_smpt_show, inode->i_private);
  114. }
  115. static int mic_smpt_debug_release(struct inode *inode, struct file *file)
  116. {
  117. return single_release(inode, file);
  118. }
  119. static const struct file_operations smpt_file_ops = {
  120. .owner = THIS_MODULE,
  121. .open = mic_smpt_debug_open,
  122. .read = seq_read,
  123. .llseek = seq_lseek,
  124. .release = mic_smpt_debug_release
  125. };
  126. static int mic_soft_reset_show(struct seq_file *s, void *pos)
  127. {
  128. struct mic_device *mdev = s->private;
  129. mic_stop(mdev, true);
  130. return 0;
  131. }
  132. static int mic_soft_reset_debug_open(struct inode *inode, struct file *file)
  133. {
  134. return single_open(file, mic_soft_reset_show, inode->i_private);
  135. }
  136. static int mic_soft_reset_debug_release(struct inode *inode, struct file *file)
  137. {
  138. return single_release(inode, file);
  139. }
  140. static const struct file_operations soft_reset_ops = {
  141. .owner = THIS_MODULE,
  142. .open = mic_soft_reset_debug_open,
  143. .read = seq_read,
  144. .llseek = seq_lseek,
  145. .release = mic_soft_reset_debug_release
  146. };
  147. static int mic_post_code_show(struct seq_file *s, void *pos)
  148. {
  149. struct mic_device *mdev = s->private;
  150. u32 reg = mdev->ops->get_postcode(mdev);
  151. seq_printf(s, "%c%c", reg & 0xff, (reg >> 8) & 0xff);
  152. return 0;
  153. }
  154. static int mic_post_code_debug_open(struct inode *inode, struct file *file)
  155. {
  156. return single_open(file, mic_post_code_show, inode->i_private);
  157. }
  158. static int mic_post_code_debug_release(struct inode *inode, struct file *file)
  159. {
  160. return single_release(inode, file);
  161. }
  162. static const struct file_operations post_code_ops = {
  163. .owner = THIS_MODULE,
  164. .open = mic_post_code_debug_open,
  165. .read = seq_read,
  166. .llseek = seq_lseek,
  167. .release = mic_post_code_debug_release
  168. };
  169. static int mic_dp_show(struct seq_file *s, void *pos)
  170. {
  171. struct mic_device *mdev = s->private;
  172. struct mic_device_desc *d;
  173. struct mic_device_ctrl *dc;
  174. struct mic_vqconfig *vqconfig;
  175. __u32 *features;
  176. __u8 *config;
  177. struct mic_bootparam *bootparam = mdev->dp;
  178. int i, j;
  179. seq_printf(s, "Bootparam: magic 0x%x\n",
  180. bootparam->magic);
  181. seq_printf(s, "Bootparam: h2c_shutdown_db %d\n",
  182. bootparam->h2c_shutdown_db);
  183. seq_printf(s, "Bootparam: h2c_config_db %d\n",
  184. bootparam->h2c_config_db);
  185. seq_printf(s, "Bootparam: c2h_shutdown_db %d\n",
  186. bootparam->c2h_shutdown_db);
  187. seq_printf(s, "Bootparam: shutdown_status %d\n",
  188. bootparam->shutdown_status);
  189. seq_printf(s, "Bootparam: shutdown_card %d\n",
  190. bootparam->shutdown_card);
  191. for (i = sizeof(*bootparam); i < MIC_DP_SIZE;
  192. i += mic_total_desc_size(d)) {
  193. d = mdev->dp + i;
  194. dc = (void *)d + mic_aligned_desc_size(d);
  195. /* end of list */
  196. if (d->type == 0)
  197. break;
  198. if (d->type == -1)
  199. continue;
  200. seq_printf(s, "Type %d ", d->type);
  201. seq_printf(s, "Num VQ %d ", d->num_vq);
  202. seq_printf(s, "Feature Len %d\n", d->feature_len);
  203. seq_printf(s, "Config Len %d ", d->config_len);
  204. seq_printf(s, "Shutdown Status %d\n", d->status);
  205. for (j = 0; j < d->num_vq; j++) {
  206. vqconfig = mic_vq_config(d) + j;
  207. seq_printf(s, "vqconfig[%d]: ", j);
  208. seq_printf(s, "address 0x%llx ", vqconfig->address);
  209. seq_printf(s, "num %d ", vqconfig->num);
  210. seq_printf(s, "used address 0x%llx\n",
  211. vqconfig->used_address);
  212. }
  213. features = (__u32 *) mic_vq_features(d);
  214. seq_printf(s, "Features: Host 0x%x ", features[0]);
  215. seq_printf(s, "Guest 0x%x\n", features[1]);
  216. config = mic_vq_configspace(d);
  217. for (j = 0; j < d->config_len; j++)
  218. seq_printf(s, "config[%d]=%d\n", j, config[j]);
  219. seq_puts(s, "Device control:\n");
  220. seq_printf(s, "Config Change %d ", dc->config_change);
  221. seq_printf(s, "Vdev reset %d\n", dc->vdev_reset);
  222. seq_printf(s, "Guest Ack %d ", dc->guest_ack);
  223. seq_printf(s, "Host ack %d\n", dc->host_ack);
  224. seq_printf(s, "Used address updated %d ",
  225. dc->used_address_updated);
  226. seq_printf(s, "Vdev 0x%llx\n", dc->vdev);
  227. seq_printf(s, "c2h doorbell %d ", dc->c2h_vdev_db);
  228. seq_printf(s, "h2c doorbell %d\n", dc->h2c_vdev_db);
  229. }
  230. return 0;
  231. }
  232. static int mic_dp_debug_open(struct inode *inode, struct file *file)
  233. {
  234. return single_open(file, mic_dp_show, inode->i_private);
  235. }
  236. static int mic_dp_debug_release(struct inode *inode, struct file *file)
  237. {
  238. return single_release(inode, file);
  239. }
  240. static const struct file_operations dp_ops = {
  241. .owner = THIS_MODULE,
  242. .open = mic_dp_debug_open,
  243. .read = seq_read,
  244. .llseek = seq_lseek,
  245. .release = mic_dp_debug_release
  246. };
  247. static int mic_vdev_info_show(struct seq_file *s, void *unused)
  248. {
  249. struct mic_device *mdev = s->private;
  250. struct list_head *pos, *tmp;
  251. struct mic_vdev *mvdev;
  252. int i, j;
  253. mutex_lock(&mdev->mic_mutex);
  254. list_for_each_safe(pos, tmp, &mdev->vdev_list) {
  255. mvdev = list_entry(pos, struct mic_vdev, list);
  256. seq_printf(s, "VDEV type %d state %s in %ld out %ld\n",
  257. mvdev->virtio_id,
  258. mic_vdevup(mvdev) ? "UP" : "DOWN",
  259. mvdev->in_bytes,
  260. mvdev->out_bytes);
  261. for (i = 0; i < MIC_MAX_VRINGS; i++) {
  262. struct vring_desc *desc;
  263. struct vring_avail *avail;
  264. struct vring_used *used;
  265. struct mic_vringh *mvr = &mvdev->mvr[i];
  266. struct vringh *vrh = &mvr->vrh;
  267. int num = vrh->vring.num;
  268. if (!num)
  269. continue;
  270. desc = vrh->vring.desc;
  271. seq_printf(s, "vring i %d avail_idx %d",
  272. i, mvr->vring.info->avail_idx & (num - 1));
  273. seq_printf(s, " vring i %d avail_idx %d\n",
  274. i, mvr->vring.info->avail_idx);
  275. seq_printf(s, "vrh i %d weak_barriers %d",
  276. i, vrh->weak_barriers);
  277. seq_printf(s, " last_avail_idx %d last_used_idx %d",
  278. vrh->last_avail_idx, vrh->last_used_idx);
  279. seq_printf(s, " completed %d\n", vrh->completed);
  280. for (j = 0; j < num; j++) {
  281. seq_printf(s, "desc[%d] addr 0x%llx len %d",
  282. j, desc->addr, desc->len);
  283. seq_printf(s, " flags 0x%x next %d\n",
  284. desc->flags,
  285. desc->next);
  286. desc++;
  287. }
  288. avail = vrh->vring.avail;
  289. seq_printf(s, "avail flags 0x%x idx %d\n",
  290. avail->flags, avail->idx & (num - 1));
  291. seq_printf(s, "avail flags 0x%x idx %d\n",
  292. avail->flags, avail->idx);
  293. for (j = 0; j < num; j++)
  294. seq_printf(s, "avail ring[%d] %d\n",
  295. j, avail->ring[j]);
  296. used = vrh->vring.used;
  297. seq_printf(s, "used flags 0x%x idx %d\n",
  298. used->flags, used->idx & (num - 1));
  299. seq_printf(s, "used flags 0x%x idx %d\n",
  300. used->flags, used->idx);
  301. for (j = 0; j < num; j++)
  302. seq_printf(s, "used ring[%d] id %d len %d\n",
  303. j, used->ring[j].id, used->ring[j].len);
  304. }
  305. }
  306. mutex_unlock(&mdev->mic_mutex);
  307. return 0;
  308. }
  309. static int mic_vdev_info_debug_open(struct inode *inode, struct file *file)
  310. {
  311. return single_open(file, mic_vdev_info_show, inode->i_private);
  312. }
  313. static int mic_vdev_info_debug_release(struct inode *inode, struct file *file)
  314. {
  315. return single_release(inode, file);
  316. }
  317. static const struct file_operations vdev_info_ops = {
  318. .owner = THIS_MODULE,
  319. .open = mic_vdev_info_debug_open,
  320. .read = seq_read,
  321. .llseek = seq_lseek,
  322. .release = mic_vdev_info_debug_release
  323. };
  324. static int mic_msi_irq_info_show(struct seq_file *s, void *pos)
  325. {
  326. struct mic_device *mdev = s->private;
  327. int reg;
  328. int i, j;
  329. u16 entry;
  330. u16 vector;
  331. struct pci_dev *pdev = container_of(mdev->sdev->parent,
  332. struct pci_dev, dev);
  333. if (pci_dev_msi_enabled(pdev)) {
  334. for (i = 0; i < mdev->irq_info.num_vectors; i++) {
  335. if (pdev->msix_enabled) {
  336. entry = mdev->irq_info.msix_entries[i].entry;
  337. vector = mdev->irq_info.msix_entries[i].vector;
  338. } else {
  339. entry = 0;
  340. vector = pdev->irq;
  341. }
  342. reg = mdev->intr_ops->read_msi_to_src_map(mdev, entry);
  343. seq_printf(s, "%s %-10d %s %-10d MXAR[%d]: %08X\n",
  344. "IRQ:", vector, "Entry:", entry, i, reg);
  345. seq_printf(s, "%-10s", "offset:");
  346. for (j = (MIC_NUM_OFFSETS - 1); j >= 0; j--)
  347. seq_printf(s, "%4d ", j);
  348. seq_puts(s, "\n");
  349. seq_printf(s, "%-10s", "count:");
  350. for (j = (MIC_NUM_OFFSETS - 1); j >= 0; j--)
  351. seq_printf(s, "%4d ",
  352. (mdev->irq_info.mic_msi_map[i] & BIT(j)) ?
  353. 1 : 0);
  354. seq_puts(s, "\n\n");
  355. }
  356. } else {
  357. seq_puts(s, "MSI/MSIx interrupts not enabled\n");
  358. }
  359. return 0;
  360. }
  361. static int mic_msi_irq_info_debug_open(struct inode *inode, struct file *file)
  362. {
  363. return single_open(file, mic_msi_irq_info_show, inode->i_private);
  364. }
  365. static int
  366. mic_msi_irq_info_debug_release(struct inode *inode, struct file *file)
  367. {
  368. return single_release(inode, file);
  369. }
  370. static const struct file_operations msi_irq_info_ops = {
  371. .owner = THIS_MODULE,
  372. .open = mic_msi_irq_info_debug_open,
  373. .read = seq_read,
  374. .llseek = seq_lseek,
  375. .release = mic_msi_irq_info_debug_release
  376. };
  377. /**
  378. * mic_create_debug_dir - Initialize MIC debugfs entries.
  379. */
  380. void mic_create_debug_dir(struct mic_device *mdev)
  381. {
  382. if (!mic_dbg)
  383. return;
  384. mdev->dbg_dir = debugfs_create_dir(dev_name(mdev->sdev), mic_dbg);
  385. if (!mdev->dbg_dir)
  386. return;
  387. debugfs_create_file("log_buf", 0444, mdev->dbg_dir,
  388. mdev, &log_buf_ops);
  389. debugfs_create_file("smpt", 0444, mdev->dbg_dir,
  390. mdev, &smpt_file_ops);
  391. debugfs_create_file("soft_reset", 0444, mdev->dbg_dir,
  392. mdev, &soft_reset_ops);
  393. debugfs_create_file("post_code", 0444, mdev->dbg_dir,
  394. mdev, &post_code_ops);
  395. debugfs_create_file("dp", 0444, mdev->dbg_dir,
  396. mdev, &dp_ops);
  397. debugfs_create_file("vdev_info", 0444, mdev->dbg_dir,
  398. mdev, &vdev_info_ops);
  399. debugfs_create_file("msi_irq_info", 0444, mdev->dbg_dir,
  400. mdev, &msi_irq_info_ops);
  401. }
  402. /**
  403. * mic_delete_debug_dir - Uninitialize MIC debugfs entries.
  404. */
  405. void mic_delete_debug_dir(struct mic_device *mdev)
  406. {
  407. if (!mdev->dbg_dir)
  408. return;
  409. debugfs_remove_recursive(mdev->dbg_dir);
  410. }
  411. /**
  412. * mic_init_debugfs - Initialize global debugfs entry.
  413. */
  414. void __init mic_init_debugfs(void)
  415. {
  416. mic_dbg = debugfs_create_dir(KBUILD_MODNAME, NULL);
  417. if (!mic_dbg)
  418. pr_err("can't create debugfs dir\n");
  419. }
  420. /**
  421. * mic_exit_debugfs - Uninitialize global debugfs entry
  422. */
  423. void mic_exit_debugfs(void)
  424. {
  425. debugfs_remove(mic_dbg);
  426. }