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