1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. 4 */ 5 #include <linux/debugfs.h> 6 #include <linux/dma-mapping.h> 7 #include <linux/slab.h> 8 #include <linux/uaccess.h> 9 10 #include <soc/tegra/bpmp.h> 11 #include <soc/tegra/bpmp-abi.h> 12 13 static DEFINE_MUTEX(bpmp_debug_lock); 14 15 struct seqbuf { 16 char *buf; 17 size_t pos; 18 size_t size; 19 }; 20 21 static void seqbuf_init(struct seqbuf *seqbuf, void *buf, size_t size) 22 { 23 seqbuf->buf = buf; 24 seqbuf->size = size; 25 seqbuf->pos = 0; 26 } 27 28 static size_t seqbuf_avail(struct seqbuf *seqbuf) 29 { 30 return seqbuf->pos < seqbuf->size ? seqbuf->size - seqbuf->pos : 0; 31 } 32 33 static size_t seqbuf_status(struct seqbuf *seqbuf) 34 { 35 return seqbuf->pos <= seqbuf->size ? 0 : -EOVERFLOW; 36 } 37 38 static int seqbuf_eof(struct seqbuf *seqbuf) 39 { 40 return seqbuf->pos >= seqbuf->size; 41 } 42 43 static int seqbuf_read(struct seqbuf *seqbuf, void *buf, size_t nbyte) 44 { 45 nbyte = min(nbyte, seqbuf_avail(seqbuf)); 46 memcpy(buf, seqbuf->buf + seqbuf->pos, nbyte); 47 seqbuf->pos += nbyte; 48 return seqbuf_status(seqbuf); 49 } 50 51 static int seqbuf_read_u32(struct seqbuf *seqbuf, uint32_t *v) 52 { 53 int err; 54 55 err = seqbuf_read(seqbuf, v, 4); 56 *v = le32_to_cpu(*v); 57 return err; 58 } 59 60 static int seqbuf_read_str(struct seqbuf *seqbuf, const char **str) 61 { 62 *str = seqbuf->buf + seqbuf->pos; 63 seqbuf->pos += strnlen(*str, seqbuf_avail(seqbuf)); 64 seqbuf->pos++; 65 return seqbuf_status(seqbuf); 66 } 67 68 static void seqbuf_seek(struct seqbuf *seqbuf, ssize_t offset) 69 { 70 seqbuf->pos += offset; 71 } 72 73 /* map filename in Linux debugfs to corresponding entry in BPMP */ 74 static const char *get_filename(struct tegra_bpmp *bpmp, 75 const struct file *file, char *buf, int size) 76 { 77 char root_path_buf[512]; 78 const char *root_path; 79 const char *filename; 80 size_t root_len; 81 82 root_path = dentry_path(bpmp->debugfs_mirror, root_path_buf, 83 sizeof(root_path_buf)); 84 if (IS_ERR(root_path)) 85 return NULL; 86 87 root_len = strlen(root_path); 88 89 filename = dentry_path(file->f_path.dentry, buf, size); 90 if (IS_ERR(filename)) 91 return NULL; 92 93 if (strlen(filename) < root_len || 94 strncmp(filename, root_path, root_len)) 95 return NULL; 96 97 filename += root_len; 98 99 return filename; 100 } 101 102 static int mrq_debug_open(struct tegra_bpmp *bpmp, const char *name, 103 uint32_t *fd, uint32_t *len, bool write) 104 { 105 struct mrq_debug_request req = { 106 .cmd = cpu_to_le32(write ? CMD_DEBUG_OPEN_WO : CMD_DEBUG_OPEN_RO), 107 }; 108 struct mrq_debug_response resp; 109 struct tegra_bpmp_message msg = { 110 .mrq = MRQ_DEBUG, 111 .tx = { 112 .data = &req, 113 .size = sizeof(req), 114 }, 115 .rx = { 116 .data = &resp, 117 .size = sizeof(resp), 118 }, 119 }; 120 ssize_t sz_name; 121 int err = 0; 122 123 sz_name = strscpy(req.fop.name, name, sizeof(req.fop.name)); 124 if (sz_name < 0) { 125 pr_err("File name too large: %s\n", name); 126 return -EINVAL; 127 } 128 129 err = tegra_bpmp_transfer(bpmp, &msg); 130 if (err < 0) 131 return err; 132 else if (msg.rx.ret < 0) 133 return -EINVAL; 134 135 *len = resp.fop.datalen; 136 *fd = resp.fop.fd; 137 138 return 0; 139 } 140 141 static int mrq_debug_close(struct tegra_bpmp *bpmp, uint32_t fd) 142 { 143 struct mrq_debug_request req = { 144 .cmd = cpu_to_le32(CMD_DEBUG_CLOSE), 145 .frd = { 146 .fd = fd, 147 }, 148 }; 149 struct mrq_debug_response resp; 150 struct tegra_bpmp_message msg = { 151 .mrq = MRQ_DEBUG, 152 .tx = { 153 .data = &req, 154 .size = sizeof(req), 155 }, 156 .rx = { 157 .data = &resp, 158 .size = sizeof(resp), 159 }, 160 }; 161 int err = 0; 162 163 err = tegra_bpmp_transfer(bpmp, &msg); 164 if (err < 0) 165 return err; 166 else if (msg.rx.ret < 0) 167 return -EINVAL; 168 169 return 0; 170 } 171 172 static int mrq_debug_read(struct tegra_bpmp *bpmp, const char *name, 173 char *data, size_t sz_data, uint32_t *nbytes) 174 { 175 struct mrq_debug_request req = { 176 .cmd = cpu_to_le32(CMD_DEBUG_READ), 177 }; 178 struct mrq_debug_response resp; 179 struct tegra_bpmp_message msg = { 180 .mrq = MRQ_DEBUG, 181 .tx = { 182 .data = &req, 183 .size = sizeof(req), 184 }, 185 .rx = { 186 .data = &resp, 187 .size = sizeof(resp), 188 }, 189 }; 190 uint32_t fd = 0, len = 0; 191 int remaining, err; 192 193 mutex_lock(&bpmp_debug_lock); 194 err = mrq_debug_open(bpmp, name, &fd, &len, 0); 195 if (err) 196 goto out; 197 198 if (len > sz_data) { 199 err = -EFBIG; 200 goto close; 201 } 202 203 req.frd.fd = fd; 204 remaining = len; 205 206 while (remaining > 0) { 207 err = tegra_bpmp_transfer(bpmp, &msg); 208 if (err < 0) { 209 goto close; 210 } else if (msg.rx.ret < 0) { 211 err = -EINVAL; 212 goto close; 213 } 214 215 if (resp.frd.readlen > remaining) { 216 pr_err("%s: read data length invalid\n", __func__); 217 err = -EINVAL; 218 goto close; 219 } 220 221 memcpy(data, resp.frd.data, resp.frd.readlen); 222 data += resp.frd.readlen; 223 remaining -= resp.frd.readlen; 224 } 225 226 *nbytes = len; 227 228 close: 229 err = mrq_debug_close(bpmp, fd); 230 out: 231 mutex_unlock(&bpmp_debug_lock); 232 return err; 233 } 234 235 static int mrq_debug_write(struct tegra_bpmp *bpmp, const char *name, 236 uint8_t *data, size_t sz_data) 237 { 238 struct mrq_debug_request req = { 239 .cmd = cpu_to_le32(CMD_DEBUG_WRITE) 240 }; 241 struct mrq_debug_response resp; 242 struct tegra_bpmp_message msg = { 243 .mrq = MRQ_DEBUG, 244 .tx = { 245 .data = &req, 246 .size = sizeof(req), 247 }, 248 .rx = { 249 .data = &resp, 250 .size = sizeof(resp), 251 }, 252 }; 253 uint32_t fd = 0, len = 0; 254 size_t remaining; 255 int err; 256 257 mutex_lock(&bpmp_debug_lock); 258 err = mrq_debug_open(bpmp, name, &fd, &len, 1); 259 if (err) 260 goto out; 261 262 if (sz_data > len) { 263 err = -EINVAL; 264 goto close; 265 } 266 267 req.fwr.fd = fd; 268 remaining = sz_data; 269 270 while (remaining > 0) { 271 len = min(remaining, sizeof(req.fwr.data)); 272 memcpy(req.fwr.data, data, len); 273 req.fwr.datalen = len; 274 275 err = tegra_bpmp_transfer(bpmp, &msg); 276 if (err < 0) { 277 goto close; 278 } else if (msg.rx.ret < 0) { 279 err = -EINVAL; 280 goto close; 281 } 282 283 data += req.fwr.datalen; 284 remaining -= req.fwr.datalen; 285 } 286 287 close: 288 err = mrq_debug_close(bpmp, fd); 289 out: 290 mutex_unlock(&bpmp_debug_lock); 291 return err; 292 } 293 294 static int bpmp_debug_show(struct seq_file *m, void *p) 295 { 296 struct file *file = m->private; 297 struct inode *inode = file_inode(file); 298 struct tegra_bpmp *bpmp = inode->i_private; 299 char *databuf = NULL; 300 char fnamebuf[256]; 301 const char *filename; 302 uint32_t nbytes = 0; 303 size_t len; 304 int err; 305 306 len = seq_get_buf(m, &databuf); 307 if (!databuf) 308 return -ENOMEM; 309 310 filename = get_filename(bpmp, file, fnamebuf, sizeof(fnamebuf)); 311 if (!filename) 312 return -ENOENT; 313 314 err = mrq_debug_read(bpmp, filename, databuf, len, &nbytes); 315 if (!err) 316 seq_commit(m, nbytes); 317 318 return err; 319 } 320 321 static ssize_t bpmp_debug_store(struct file *file, const char __user *buf, 322 size_t count, loff_t *f_pos) 323 { 324 struct inode *inode = file_inode(file); 325 struct tegra_bpmp *bpmp = inode->i_private; 326 char *databuf = NULL; 327 char fnamebuf[256]; 328 const char *filename; 329 ssize_t err; 330 331 filename = get_filename(bpmp, file, fnamebuf, sizeof(fnamebuf)); 332 if (!filename) 333 return -ENOENT; 334 335 databuf = kmalloc(count, GFP_KERNEL); 336 if (!databuf) 337 return -ENOMEM; 338 339 if (copy_from_user(databuf, buf, count)) { 340 err = -EFAULT; 341 goto free_ret; 342 } 343 344 err = mrq_debug_write(bpmp, filename, databuf, count); 345 346 free_ret: 347 kfree(databuf); 348 349 return err ?: count; 350 } 351 352 static int bpmp_debug_open(struct inode *inode, struct file *file) 353 { 354 return single_open_size(file, bpmp_debug_show, file, SZ_256K); 355 } 356 357 static const struct file_operations bpmp_debug_fops = { 358 .open = bpmp_debug_open, 359 .read = seq_read, 360 .llseek = seq_lseek, 361 .write = bpmp_debug_store, 362 .release = single_release, 363 }; 364 365 static int bpmp_populate_debugfs_inband(struct tegra_bpmp *bpmp, 366 struct dentry *parent, 367 char *ppath) 368 { 369 const size_t pathlen = SZ_256; 370 const size_t bufsize = SZ_16K; 371 uint32_t dsize, attrs = 0; 372 struct dentry *dentry; 373 struct seqbuf seqbuf; 374 char *buf, *pathbuf; 375 const char *name; 376 int err = 0; 377 378 if (!bpmp || !parent || !ppath) 379 return -EINVAL; 380 381 buf = kmalloc(bufsize, GFP_KERNEL); 382 if (!buf) 383 return -ENOMEM; 384 385 pathbuf = kzalloc(pathlen, GFP_KERNEL); 386 if (!pathbuf) { 387 kfree(buf); 388 return -ENOMEM; 389 } 390 391 err = mrq_debug_read(bpmp, ppath, buf, bufsize, &dsize); 392 if (err) 393 goto out; 394 395 seqbuf_init(&seqbuf, buf, dsize); 396 397 while (!seqbuf_eof(&seqbuf)) { 398 err = seqbuf_read_u32(&seqbuf, &attrs); 399 if (err) 400 goto out; 401 402 err = seqbuf_read_str(&seqbuf, &name); 403 if (err < 0) 404 goto out; 405 406 if (attrs & DEBUGFS_S_ISDIR) { 407 size_t len; 408 409 dentry = debugfs_create_dir(name, parent); 410 if (IS_ERR(dentry)) { 411 err = PTR_ERR(dentry); 412 goto out; 413 } 414 415 len = snprintf(pathbuf, pathlen, "%s%s/", ppath, name); 416 if (len >= pathlen) { 417 err = -EINVAL; 418 goto out; 419 } 420 421 err = bpmp_populate_debugfs_inband(bpmp, dentry, 422 pathbuf); 423 if (err < 0) 424 goto out; 425 } else { 426 umode_t mode; 427 428 mode = attrs & DEBUGFS_S_IRUSR ? 0400 : 0; 429 mode |= attrs & DEBUGFS_S_IWUSR ? 0200 : 0; 430 dentry = debugfs_create_file(name, mode, parent, bpmp, 431 &bpmp_debug_fops); 432 if (!dentry) { 433 err = -ENOMEM; 434 goto out; 435 } 436 } 437 } 438 439 out: 440 kfree(pathbuf); 441 kfree(buf); 442 443 return err; 444 } 445 446 static int mrq_debugfs_read(struct tegra_bpmp *bpmp, 447 dma_addr_t name, size_t sz_name, 448 dma_addr_t data, size_t sz_data, 449 size_t *nbytes) 450 { 451 struct mrq_debugfs_request req = { 452 .cmd = cpu_to_le32(CMD_DEBUGFS_READ), 453 .fop = { 454 .fnameaddr = cpu_to_le32((uint32_t)name), 455 .fnamelen = cpu_to_le32((uint32_t)sz_name), 456 .dataaddr = cpu_to_le32((uint32_t)data), 457 .datalen = cpu_to_le32((uint32_t)sz_data), 458 }, 459 }; 460 struct mrq_debugfs_response resp; 461 struct tegra_bpmp_message msg = { 462 .mrq = MRQ_DEBUGFS, 463 .tx = { 464 .data = &req, 465 .size = sizeof(req), 466 }, 467 .rx = { 468 .data = &resp, 469 .size = sizeof(resp), 470 }, 471 }; 472 int err; 473 474 err = tegra_bpmp_transfer(bpmp, &msg); 475 if (err < 0) 476 return err; 477 else if (msg.rx.ret < 0) 478 return -EINVAL; 479 480 *nbytes = (size_t)resp.fop.nbytes; 481 482 return 0; 483 } 484 485 static int mrq_debugfs_write(struct tegra_bpmp *bpmp, 486 dma_addr_t name, size_t sz_name, 487 dma_addr_t data, size_t sz_data) 488 { 489 const struct mrq_debugfs_request req = { 490 .cmd = cpu_to_le32(CMD_DEBUGFS_WRITE), 491 .fop = { 492 .fnameaddr = cpu_to_le32((uint32_t)name), 493 .fnamelen = cpu_to_le32((uint32_t)sz_name), 494 .dataaddr = cpu_to_le32((uint32_t)data), 495 .datalen = cpu_to_le32((uint32_t)sz_data), 496 }, 497 }; 498 struct tegra_bpmp_message msg = { 499 .mrq = MRQ_DEBUGFS, 500 .tx = { 501 .data = &req, 502 .size = sizeof(req), 503 }, 504 }; 505 506 return tegra_bpmp_transfer(bpmp, &msg); 507 } 508 509 static int mrq_debugfs_dumpdir(struct tegra_bpmp *bpmp, dma_addr_t addr, 510 size_t size, size_t *nbytes) 511 { 512 const struct mrq_debugfs_request req = { 513 .cmd = cpu_to_le32(CMD_DEBUGFS_DUMPDIR), 514 .dumpdir = { 515 .dataaddr = cpu_to_le32((uint32_t)addr), 516 .datalen = cpu_to_le32((uint32_t)size), 517 }, 518 }; 519 struct mrq_debugfs_response resp; 520 struct tegra_bpmp_message msg = { 521 .mrq = MRQ_DEBUGFS, 522 .tx = { 523 .data = &req, 524 .size = sizeof(req), 525 }, 526 .rx = { 527 .data = &resp, 528 .size = sizeof(resp), 529 }, 530 }; 531 int err; 532 533 err = tegra_bpmp_transfer(bpmp, &msg); 534 if (err < 0) 535 return err; 536 else if (msg.rx.ret < 0) 537 return -EINVAL; 538 539 *nbytes = (size_t)resp.dumpdir.nbytes; 540 541 return 0; 542 } 543 544 static int debugfs_show(struct seq_file *m, void *p) 545 { 546 struct file *file = m->private; 547 struct inode *inode = file_inode(file); 548 struct tegra_bpmp *bpmp = inode->i_private; 549 const size_t datasize = m->size; 550 const size_t namesize = SZ_256; 551 void *datavirt, *namevirt; 552 dma_addr_t dataphys, namephys; 553 char buf[256]; 554 const char *filename; 555 size_t len, nbytes; 556 int err; 557 558 filename = get_filename(bpmp, file, buf, sizeof(buf)); 559 if (!filename) 560 return -ENOENT; 561 562 namevirt = dma_alloc_coherent(bpmp->dev, namesize, &namephys, 563 GFP_KERNEL | GFP_DMA32); 564 if (!namevirt) 565 return -ENOMEM; 566 567 datavirt = dma_alloc_coherent(bpmp->dev, datasize, &dataphys, 568 GFP_KERNEL | GFP_DMA32); 569 if (!datavirt) { 570 err = -ENOMEM; 571 goto free_namebuf; 572 } 573 574 len = strlen(filename); 575 strncpy(namevirt, filename, namesize); 576 577 err = mrq_debugfs_read(bpmp, namephys, len, dataphys, datasize, 578 &nbytes); 579 580 if (!err) 581 seq_write(m, datavirt, nbytes); 582 583 dma_free_coherent(bpmp->dev, datasize, datavirt, dataphys); 584 free_namebuf: 585 dma_free_coherent(bpmp->dev, namesize, namevirt, namephys); 586 587 return err; 588 } 589 590 static int debugfs_open(struct inode *inode, struct file *file) 591 { 592 return single_open_size(file, debugfs_show, file, SZ_128K); 593 } 594 595 static ssize_t debugfs_store(struct file *file, const char __user *buf, 596 size_t count, loff_t *f_pos) 597 { 598 struct inode *inode = file_inode(file); 599 struct tegra_bpmp *bpmp = inode->i_private; 600 const size_t datasize = count; 601 const size_t namesize = SZ_256; 602 void *datavirt, *namevirt; 603 dma_addr_t dataphys, namephys; 604 char fnamebuf[256]; 605 const char *filename; 606 size_t len; 607 int err; 608 609 filename = get_filename(bpmp, file, fnamebuf, sizeof(fnamebuf)); 610 if (!filename) 611 return -ENOENT; 612 613 namevirt = dma_alloc_coherent(bpmp->dev, namesize, &namephys, 614 GFP_KERNEL | GFP_DMA32); 615 if (!namevirt) 616 return -ENOMEM; 617 618 datavirt = dma_alloc_coherent(bpmp->dev, datasize, &dataphys, 619 GFP_KERNEL | GFP_DMA32); 620 if (!datavirt) { 621 err = -ENOMEM; 622 goto free_namebuf; 623 } 624 625 len = strlen(filename); 626 strncpy(namevirt, filename, namesize); 627 628 if (copy_from_user(datavirt, buf, count)) { 629 err = -EFAULT; 630 goto free_databuf; 631 } 632 633 err = mrq_debugfs_write(bpmp, namephys, len, dataphys, 634 count); 635 636 free_databuf: 637 dma_free_coherent(bpmp->dev, datasize, datavirt, dataphys); 638 free_namebuf: 639 dma_free_coherent(bpmp->dev, namesize, namevirt, namephys); 640 641 return err ?: count; 642 } 643 644 static const struct file_operations debugfs_fops = { 645 .open = debugfs_open, 646 .read = seq_read, 647 .llseek = seq_lseek, 648 .write = debugfs_store, 649 .release = single_release, 650 }; 651 652 static int bpmp_populate_dir(struct tegra_bpmp *bpmp, struct seqbuf *seqbuf, 653 struct dentry *parent, uint32_t depth) 654 { 655 int err; 656 uint32_t d, t; 657 const char *name; 658 struct dentry *dentry; 659 660 while (!seqbuf_eof(seqbuf)) { 661 err = seqbuf_read_u32(seqbuf, &d); 662 if (err < 0) 663 return err; 664 665 if (d < depth) { 666 seqbuf_seek(seqbuf, -4); 667 /* go up a level */ 668 return 0; 669 } else if (d != depth) { 670 /* malformed data received from BPMP */ 671 return -EIO; 672 } 673 674 err = seqbuf_read_u32(seqbuf, &t); 675 if (err < 0) 676 return err; 677 err = seqbuf_read_str(seqbuf, &name); 678 if (err < 0) 679 return err; 680 681 if (t & DEBUGFS_S_ISDIR) { 682 dentry = debugfs_create_dir(name, parent); 683 if (!dentry) 684 return -ENOMEM; 685 err = bpmp_populate_dir(bpmp, seqbuf, dentry, depth+1); 686 if (err < 0) 687 return err; 688 } else { 689 umode_t mode; 690 691 mode = t & DEBUGFS_S_IRUSR ? S_IRUSR : 0; 692 mode |= t & DEBUGFS_S_IWUSR ? S_IWUSR : 0; 693 dentry = debugfs_create_file(name, mode, 694 parent, bpmp, 695 &debugfs_fops); 696 if (!dentry) 697 return -ENOMEM; 698 } 699 } 700 701 return 0; 702 } 703 704 static int bpmp_populate_debugfs_shmem(struct tegra_bpmp *bpmp) 705 { 706 struct seqbuf seqbuf; 707 const size_t sz = SZ_512K; 708 dma_addr_t phys; 709 size_t nbytes; 710 void *virt; 711 int err; 712 713 virt = dma_alloc_coherent(bpmp->dev, sz, &phys, 714 GFP_KERNEL | GFP_DMA32); 715 if (!virt) 716 return -ENOMEM; 717 718 err = mrq_debugfs_dumpdir(bpmp, phys, sz, &nbytes); 719 if (err < 0) { 720 goto free; 721 } else if (nbytes > sz) { 722 err = -EINVAL; 723 goto free; 724 } 725 726 seqbuf_init(&seqbuf, virt, nbytes); 727 err = bpmp_populate_dir(bpmp, &seqbuf, bpmp->debugfs_mirror, 0); 728 free: 729 dma_free_coherent(bpmp->dev, sz, virt, phys); 730 731 return err; 732 } 733 734 int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp) 735 { 736 struct dentry *root; 737 bool inband; 738 int err; 739 740 inband = tegra_bpmp_mrq_is_supported(bpmp, MRQ_DEBUG); 741 742 if (!inband && !tegra_bpmp_mrq_is_supported(bpmp, MRQ_DEBUGFS)) 743 return 0; 744 745 root = debugfs_create_dir("bpmp", NULL); 746 if (!root) 747 return -ENOMEM; 748 749 bpmp->debugfs_mirror = debugfs_create_dir("debug", root); 750 if (!bpmp->debugfs_mirror) { 751 err = -ENOMEM; 752 goto out; 753 } 754 755 if (inband) 756 err = bpmp_populate_debugfs_inband(bpmp, bpmp->debugfs_mirror, 757 "/"); 758 else 759 err = bpmp_populate_debugfs_shmem(bpmp); 760 761 out: 762 if (err < 0) 763 debugfs_remove_recursive(root); 764 765 return err; 766 } 767