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 fnamebuf[256]; 300 const char *filename; 301 struct mrq_debug_request req = { 302 .cmd = cpu_to_le32(CMD_DEBUG_READ), 303 }; 304 struct mrq_debug_response resp; 305 struct tegra_bpmp_message msg = { 306 .mrq = MRQ_DEBUG, 307 .tx = { 308 .data = &req, 309 .size = sizeof(req), 310 }, 311 .rx = { 312 .data = &resp, 313 .size = sizeof(resp), 314 }, 315 }; 316 uint32_t fd = 0, len = 0; 317 int remaining, err; 318 319 filename = get_filename(bpmp, file, fnamebuf, sizeof(fnamebuf)); 320 if (!filename) 321 return -ENOENT; 322 323 mutex_lock(&bpmp_debug_lock); 324 err = mrq_debug_open(bpmp, filename, &fd, &len, 0); 325 if (err) 326 goto out; 327 328 req.frd.fd = fd; 329 remaining = len; 330 331 while (remaining > 0) { 332 err = tegra_bpmp_transfer(bpmp, &msg); 333 if (err < 0) { 334 goto close; 335 } else if (msg.rx.ret < 0) { 336 err = -EINVAL; 337 goto close; 338 } 339 340 if (resp.frd.readlen > remaining) { 341 pr_err("%s: read data length invalid\n", __func__); 342 err = -EINVAL; 343 goto close; 344 } 345 346 seq_write(m, resp.frd.data, resp.frd.readlen); 347 remaining -= resp.frd.readlen; 348 } 349 350 close: 351 err = mrq_debug_close(bpmp, fd); 352 out: 353 mutex_unlock(&bpmp_debug_lock); 354 return err; 355 } 356 357 static ssize_t bpmp_debug_store(struct file *file, const char __user *buf, 358 size_t count, loff_t *f_pos) 359 { 360 struct inode *inode = file_inode(file); 361 struct tegra_bpmp *bpmp = inode->i_private; 362 char *databuf = NULL; 363 char fnamebuf[256]; 364 const char *filename; 365 ssize_t err; 366 367 filename = get_filename(bpmp, file, fnamebuf, sizeof(fnamebuf)); 368 if (!filename) 369 return -ENOENT; 370 371 databuf = kmalloc(count, GFP_KERNEL); 372 if (!databuf) 373 return -ENOMEM; 374 375 if (copy_from_user(databuf, buf, count)) { 376 err = -EFAULT; 377 goto free_ret; 378 } 379 380 err = mrq_debug_write(bpmp, filename, databuf, count); 381 382 free_ret: 383 kfree(databuf); 384 385 return err ?: count; 386 } 387 388 static int bpmp_debug_open(struct inode *inode, struct file *file) 389 { 390 return single_open_size(file, bpmp_debug_show, file, SZ_256K); 391 } 392 393 static const struct file_operations bpmp_debug_fops = { 394 .open = bpmp_debug_open, 395 .read = seq_read, 396 .llseek = seq_lseek, 397 .write = bpmp_debug_store, 398 .release = single_release, 399 }; 400 401 static int bpmp_populate_debugfs_inband(struct tegra_bpmp *bpmp, 402 struct dentry *parent, 403 char *ppath) 404 { 405 const size_t pathlen = SZ_256; 406 const size_t bufsize = SZ_16K; 407 uint32_t dsize, attrs = 0; 408 struct dentry *dentry; 409 struct seqbuf seqbuf; 410 char *buf, *pathbuf; 411 const char *name; 412 int err = 0; 413 414 if (!bpmp || !parent || !ppath) 415 return -EINVAL; 416 417 buf = kmalloc(bufsize, GFP_KERNEL); 418 if (!buf) 419 return -ENOMEM; 420 421 pathbuf = kzalloc(pathlen, GFP_KERNEL); 422 if (!pathbuf) { 423 kfree(buf); 424 return -ENOMEM; 425 } 426 427 err = mrq_debug_read(bpmp, ppath, buf, bufsize, &dsize); 428 if (err) 429 goto out; 430 431 seqbuf_init(&seqbuf, buf, dsize); 432 433 while (!seqbuf_eof(&seqbuf)) { 434 err = seqbuf_read_u32(&seqbuf, &attrs); 435 if (err) 436 goto out; 437 438 err = seqbuf_read_str(&seqbuf, &name); 439 if (err < 0) 440 goto out; 441 442 if (attrs & DEBUGFS_S_ISDIR) { 443 size_t len; 444 445 dentry = debugfs_create_dir(name, parent); 446 if (IS_ERR(dentry)) { 447 err = PTR_ERR(dentry); 448 goto out; 449 } 450 451 len = snprintf(pathbuf, pathlen, "%s%s/", ppath, name); 452 if (len >= pathlen) { 453 err = -EINVAL; 454 goto out; 455 } 456 457 err = bpmp_populate_debugfs_inband(bpmp, dentry, 458 pathbuf); 459 if (err < 0) 460 goto out; 461 } else { 462 umode_t mode; 463 464 mode = attrs & DEBUGFS_S_IRUSR ? 0400 : 0; 465 mode |= attrs & DEBUGFS_S_IWUSR ? 0200 : 0; 466 dentry = debugfs_create_file(name, mode, parent, bpmp, 467 &bpmp_debug_fops); 468 if (!dentry) { 469 err = -ENOMEM; 470 goto out; 471 } 472 } 473 } 474 475 out: 476 kfree(pathbuf); 477 kfree(buf); 478 479 return err; 480 } 481 482 static int mrq_debugfs_read(struct tegra_bpmp *bpmp, 483 dma_addr_t name, size_t sz_name, 484 dma_addr_t data, size_t sz_data, 485 size_t *nbytes) 486 { 487 struct mrq_debugfs_request req = { 488 .cmd = cpu_to_le32(CMD_DEBUGFS_READ), 489 .fop = { 490 .fnameaddr = cpu_to_le32((uint32_t)name), 491 .fnamelen = cpu_to_le32((uint32_t)sz_name), 492 .dataaddr = cpu_to_le32((uint32_t)data), 493 .datalen = cpu_to_le32((uint32_t)sz_data), 494 }, 495 }; 496 struct mrq_debugfs_response resp; 497 struct tegra_bpmp_message msg = { 498 .mrq = MRQ_DEBUGFS, 499 .tx = { 500 .data = &req, 501 .size = sizeof(req), 502 }, 503 .rx = { 504 .data = &resp, 505 .size = sizeof(resp), 506 }, 507 }; 508 int err; 509 510 err = tegra_bpmp_transfer(bpmp, &msg); 511 if (err < 0) 512 return err; 513 else if (msg.rx.ret < 0) 514 return -EINVAL; 515 516 *nbytes = (size_t)resp.fop.nbytes; 517 518 return 0; 519 } 520 521 static int mrq_debugfs_write(struct tegra_bpmp *bpmp, 522 dma_addr_t name, size_t sz_name, 523 dma_addr_t data, size_t sz_data) 524 { 525 const struct mrq_debugfs_request req = { 526 .cmd = cpu_to_le32(CMD_DEBUGFS_WRITE), 527 .fop = { 528 .fnameaddr = cpu_to_le32((uint32_t)name), 529 .fnamelen = cpu_to_le32((uint32_t)sz_name), 530 .dataaddr = cpu_to_le32((uint32_t)data), 531 .datalen = cpu_to_le32((uint32_t)sz_data), 532 }, 533 }; 534 struct tegra_bpmp_message msg = { 535 .mrq = MRQ_DEBUGFS, 536 .tx = { 537 .data = &req, 538 .size = sizeof(req), 539 }, 540 }; 541 542 return tegra_bpmp_transfer(bpmp, &msg); 543 } 544 545 static int mrq_debugfs_dumpdir(struct tegra_bpmp *bpmp, dma_addr_t addr, 546 size_t size, size_t *nbytes) 547 { 548 const struct mrq_debugfs_request req = { 549 .cmd = cpu_to_le32(CMD_DEBUGFS_DUMPDIR), 550 .dumpdir = { 551 .dataaddr = cpu_to_le32((uint32_t)addr), 552 .datalen = cpu_to_le32((uint32_t)size), 553 }, 554 }; 555 struct mrq_debugfs_response resp; 556 struct tegra_bpmp_message msg = { 557 .mrq = MRQ_DEBUGFS, 558 .tx = { 559 .data = &req, 560 .size = sizeof(req), 561 }, 562 .rx = { 563 .data = &resp, 564 .size = sizeof(resp), 565 }, 566 }; 567 int err; 568 569 err = tegra_bpmp_transfer(bpmp, &msg); 570 if (err < 0) 571 return err; 572 else if (msg.rx.ret < 0) 573 return -EINVAL; 574 575 *nbytes = (size_t)resp.dumpdir.nbytes; 576 577 return 0; 578 } 579 580 static int debugfs_show(struct seq_file *m, void *p) 581 { 582 struct file *file = m->private; 583 struct inode *inode = file_inode(file); 584 struct tegra_bpmp *bpmp = inode->i_private; 585 const size_t datasize = m->size; 586 const size_t namesize = SZ_256; 587 void *datavirt, *namevirt; 588 dma_addr_t dataphys, namephys; 589 char buf[256]; 590 const char *filename; 591 size_t len, nbytes; 592 int err; 593 594 filename = get_filename(bpmp, file, buf, sizeof(buf)); 595 if (!filename) 596 return -ENOENT; 597 598 namevirt = dma_alloc_coherent(bpmp->dev, namesize, &namephys, 599 GFP_KERNEL | GFP_DMA32); 600 if (!namevirt) 601 return -ENOMEM; 602 603 datavirt = dma_alloc_coherent(bpmp->dev, datasize, &dataphys, 604 GFP_KERNEL | GFP_DMA32); 605 if (!datavirt) { 606 err = -ENOMEM; 607 goto free_namebuf; 608 } 609 610 len = strlen(filename); 611 strncpy(namevirt, filename, namesize); 612 613 err = mrq_debugfs_read(bpmp, namephys, len, dataphys, datasize, 614 &nbytes); 615 616 if (!err) 617 seq_write(m, datavirt, nbytes); 618 619 dma_free_coherent(bpmp->dev, datasize, datavirt, dataphys); 620 free_namebuf: 621 dma_free_coherent(bpmp->dev, namesize, namevirt, namephys); 622 623 return err; 624 } 625 626 static int debugfs_open(struct inode *inode, struct file *file) 627 { 628 return single_open_size(file, debugfs_show, file, SZ_128K); 629 } 630 631 static ssize_t debugfs_store(struct file *file, const char __user *buf, 632 size_t count, loff_t *f_pos) 633 { 634 struct inode *inode = file_inode(file); 635 struct tegra_bpmp *bpmp = inode->i_private; 636 const size_t datasize = count; 637 const size_t namesize = SZ_256; 638 void *datavirt, *namevirt; 639 dma_addr_t dataphys, namephys; 640 char fnamebuf[256]; 641 const char *filename; 642 size_t len; 643 int err; 644 645 filename = get_filename(bpmp, file, fnamebuf, sizeof(fnamebuf)); 646 if (!filename) 647 return -ENOENT; 648 649 namevirt = dma_alloc_coherent(bpmp->dev, namesize, &namephys, 650 GFP_KERNEL | GFP_DMA32); 651 if (!namevirt) 652 return -ENOMEM; 653 654 datavirt = dma_alloc_coherent(bpmp->dev, datasize, &dataphys, 655 GFP_KERNEL | GFP_DMA32); 656 if (!datavirt) { 657 err = -ENOMEM; 658 goto free_namebuf; 659 } 660 661 len = strlen(filename); 662 strncpy(namevirt, filename, namesize); 663 664 if (copy_from_user(datavirt, buf, count)) { 665 err = -EFAULT; 666 goto free_databuf; 667 } 668 669 err = mrq_debugfs_write(bpmp, namephys, len, dataphys, 670 count); 671 672 free_databuf: 673 dma_free_coherent(bpmp->dev, datasize, datavirt, dataphys); 674 free_namebuf: 675 dma_free_coherent(bpmp->dev, namesize, namevirt, namephys); 676 677 return err ?: count; 678 } 679 680 static const struct file_operations debugfs_fops = { 681 .open = debugfs_open, 682 .read = seq_read, 683 .llseek = seq_lseek, 684 .write = debugfs_store, 685 .release = single_release, 686 }; 687 688 static int bpmp_populate_dir(struct tegra_bpmp *bpmp, struct seqbuf *seqbuf, 689 struct dentry *parent, uint32_t depth) 690 { 691 int err; 692 uint32_t d, t; 693 const char *name; 694 struct dentry *dentry; 695 696 while (!seqbuf_eof(seqbuf)) { 697 err = seqbuf_read_u32(seqbuf, &d); 698 if (err < 0) 699 return err; 700 701 if (d < depth) { 702 seqbuf_seek(seqbuf, -4); 703 /* go up a level */ 704 return 0; 705 } else if (d != depth) { 706 /* malformed data received from BPMP */ 707 return -EIO; 708 } 709 710 err = seqbuf_read_u32(seqbuf, &t); 711 if (err < 0) 712 return err; 713 err = seqbuf_read_str(seqbuf, &name); 714 if (err < 0) 715 return err; 716 717 if (t & DEBUGFS_S_ISDIR) { 718 dentry = debugfs_create_dir(name, parent); 719 if (!dentry) 720 return -ENOMEM; 721 err = bpmp_populate_dir(bpmp, seqbuf, dentry, depth+1); 722 if (err < 0) 723 return err; 724 } else { 725 umode_t mode; 726 727 mode = t & DEBUGFS_S_IRUSR ? S_IRUSR : 0; 728 mode |= t & DEBUGFS_S_IWUSR ? S_IWUSR : 0; 729 dentry = debugfs_create_file(name, mode, 730 parent, bpmp, 731 &debugfs_fops); 732 if (!dentry) 733 return -ENOMEM; 734 } 735 } 736 737 return 0; 738 } 739 740 static int bpmp_populate_debugfs_shmem(struct tegra_bpmp *bpmp) 741 { 742 struct seqbuf seqbuf; 743 const size_t sz = SZ_512K; 744 dma_addr_t phys; 745 size_t nbytes; 746 void *virt; 747 int err; 748 749 virt = dma_alloc_coherent(bpmp->dev, sz, &phys, 750 GFP_KERNEL | GFP_DMA32); 751 if (!virt) 752 return -ENOMEM; 753 754 err = mrq_debugfs_dumpdir(bpmp, phys, sz, &nbytes); 755 if (err < 0) { 756 goto free; 757 } else if (nbytes > sz) { 758 err = -EINVAL; 759 goto free; 760 } 761 762 seqbuf_init(&seqbuf, virt, nbytes); 763 err = bpmp_populate_dir(bpmp, &seqbuf, bpmp->debugfs_mirror, 0); 764 free: 765 dma_free_coherent(bpmp->dev, sz, virt, phys); 766 767 return err; 768 } 769 770 int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp) 771 { 772 struct dentry *root; 773 bool inband; 774 int err; 775 776 inband = tegra_bpmp_mrq_is_supported(bpmp, MRQ_DEBUG); 777 778 if (!inband && !tegra_bpmp_mrq_is_supported(bpmp, MRQ_DEBUGFS)) 779 return 0; 780 781 root = debugfs_create_dir("bpmp", NULL); 782 if (!root) 783 return -ENOMEM; 784 785 bpmp->debugfs_mirror = debugfs_create_dir("debug", root); 786 if (!bpmp->debugfs_mirror) { 787 err = -ENOMEM; 788 goto out; 789 } 790 791 if (inband) 792 err = bpmp_populate_debugfs_inband(bpmp, bpmp->debugfs_mirror, 793 "/"); 794 else 795 err = bpmp_populate_debugfs_shmem(bpmp); 796 797 out: 798 if (err < 0) 799 debugfs_remove_recursive(root); 800 801 return err; 802 } 803