root/drivers/misc/habanalabs/debugfs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hl_debugfs_i2c_read
  2. hl_debugfs_i2c_write
  3. hl_debugfs_led_set
  4. command_buffers_show
  5. command_submission_show
  6. command_submission_jobs_show
  7. userptr_show
  8. vm_show
  9. get_hop0_addr
  10. get_hop0_pte_addr
  11. get_hop1_pte_addr
  12. get_hop2_pte_addr
  13. get_hop3_pte_addr
  14. get_hop4_pte_addr
  15. get_next_hop_addr
  16. mmu_show
  17. mmu_write
  18. engines_show
  19. hl_is_device_va
  20. device_va_to_pa
  21. hl_data_read32
  22. hl_data_write32
  23. hl_get_power_state
  24. hl_set_power_state
  25. hl_i2c_data_read
  26. hl_i2c_data_write
  27. hl_led0_write
  28. hl_led1_write
  29. hl_led2_write
  30. hl_device_read
  31. hl_device_write
  32. hl_debugfs_open
  33. hl_debugfs_write
  34. hl_debugfs_add_device
  35. hl_debugfs_remove_device
  36. hl_debugfs_add_file
  37. hl_debugfs_remove_file
  38. hl_debugfs_add_cb
  39. hl_debugfs_remove_cb
  40. hl_debugfs_add_cs
  41. hl_debugfs_remove_cs
  42. hl_debugfs_add_job
  43. hl_debugfs_remove_job
  44. hl_debugfs_add_userptr
  45. hl_debugfs_remove_userptr
  46. hl_debugfs_add_ctx_mem_hash
  47. hl_debugfs_remove_ctx_mem_hash
  48. hl_debugfs_init
  49. hl_debugfs_fini

   1 // SPDX-License-Identifier: GPL-2.0
   2 
   3 /*
   4  * Copyright 2016-2019 HabanaLabs, Ltd.
   5  * All Rights Reserved.
   6  */
   7 
   8 #include "habanalabs.h"
   9 #include "include/hw_ip/mmu/mmu_general.h"
  10 
  11 #include <linux/pci.h>
  12 #include <linux/debugfs.h>
  13 #include <linux/uaccess.h>
  14 
  15 #define MMU_ADDR_BUF_SIZE       40
  16 #define MMU_ASID_BUF_SIZE       10
  17 #define MMU_KBUF_SIZE           (MMU_ADDR_BUF_SIZE + MMU_ASID_BUF_SIZE)
  18 
  19 static struct dentry *hl_debug_root;
  20 
  21 static int hl_debugfs_i2c_read(struct hl_device *hdev, u8 i2c_bus, u8 i2c_addr,
  22                                 u8 i2c_reg, u32 *val)
  23 {
  24         struct armcp_packet pkt;
  25         int rc;
  26 
  27         if (hl_device_disabled_or_in_reset(hdev))
  28                 return -EBUSY;
  29 
  30         memset(&pkt, 0, sizeof(pkt));
  31 
  32         pkt.ctl = cpu_to_le32(ARMCP_PACKET_I2C_RD <<
  33                                 ARMCP_PKT_CTL_OPCODE_SHIFT);
  34         pkt.i2c_bus = i2c_bus;
  35         pkt.i2c_addr = i2c_addr;
  36         pkt.i2c_reg = i2c_reg;
  37 
  38         rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
  39                                         HL_DEVICE_TIMEOUT_USEC, (long *) val);
  40 
  41         if (rc)
  42                 dev_err(hdev->dev, "Failed to read from I2C, error %d\n", rc);
  43 
  44         return rc;
  45 }
  46 
  47 static int hl_debugfs_i2c_write(struct hl_device *hdev, u8 i2c_bus, u8 i2c_addr,
  48                                 u8 i2c_reg, u32 val)
  49 {
  50         struct armcp_packet pkt;
  51         int rc;
  52 
  53         if (hl_device_disabled_or_in_reset(hdev))
  54                 return -EBUSY;
  55 
  56         memset(&pkt, 0, sizeof(pkt));
  57 
  58         pkt.ctl = cpu_to_le32(ARMCP_PACKET_I2C_WR <<
  59                                 ARMCP_PKT_CTL_OPCODE_SHIFT);
  60         pkt.i2c_bus = i2c_bus;
  61         pkt.i2c_addr = i2c_addr;
  62         pkt.i2c_reg = i2c_reg;
  63         pkt.value = cpu_to_le64(val);
  64 
  65         rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
  66                                         HL_DEVICE_TIMEOUT_USEC, NULL);
  67 
  68         if (rc)
  69                 dev_err(hdev->dev, "Failed to write to I2C, error %d\n", rc);
  70 
  71         return rc;
  72 }
  73 
  74 static void hl_debugfs_led_set(struct hl_device *hdev, u8 led, u8 state)
  75 {
  76         struct armcp_packet pkt;
  77         int rc;
  78 
  79         if (hl_device_disabled_or_in_reset(hdev))
  80                 return;
  81 
  82         memset(&pkt, 0, sizeof(pkt));
  83 
  84         pkt.ctl = cpu_to_le32(ARMCP_PACKET_LED_SET <<
  85                                 ARMCP_PKT_CTL_OPCODE_SHIFT);
  86         pkt.led_index = cpu_to_le32(led);
  87         pkt.value = cpu_to_le64(state);
  88 
  89         rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
  90                                                 HL_DEVICE_TIMEOUT_USEC, NULL);
  91 
  92         if (rc)
  93                 dev_err(hdev->dev, "Failed to set LED %d, error %d\n", led, rc);
  94 }
  95 
  96 static int command_buffers_show(struct seq_file *s, void *data)
  97 {
  98         struct hl_debugfs_entry *entry = s->private;
  99         struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
 100         struct hl_cb *cb;
 101         bool first = true;
 102 
 103         spin_lock(&dev_entry->cb_spinlock);
 104 
 105         list_for_each_entry(cb, &dev_entry->cb_list, debugfs_list) {
 106                 if (first) {
 107                         first = false;
 108                         seq_puts(s, "\n");
 109                         seq_puts(s, " CB ID   CTX ID   CB size    CB RefCnt    mmap?   CS counter\n");
 110                         seq_puts(s, "---------------------------------------------------------------\n");
 111                 }
 112                 seq_printf(s,
 113                         "   %03d        %d    0x%08x      %d          %d          %d\n",
 114                         cb->id, cb->ctx_id, cb->size,
 115                         kref_read(&cb->refcount),
 116                         cb->mmap, cb->cs_cnt);
 117         }
 118 
 119         spin_unlock(&dev_entry->cb_spinlock);
 120 
 121         if (!first)
 122                 seq_puts(s, "\n");
 123 
 124         return 0;
 125 }
 126 
 127 static int command_submission_show(struct seq_file *s, void *data)
 128 {
 129         struct hl_debugfs_entry *entry = s->private;
 130         struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
 131         struct hl_cs *cs;
 132         bool first = true;
 133 
 134         spin_lock(&dev_entry->cs_spinlock);
 135 
 136         list_for_each_entry(cs, &dev_entry->cs_list, debugfs_list) {
 137                 if (first) {
 138                         first = false;
 139                         seq_puts(s, "\n");
 140                         seq_puts(s, " CS ID   CTX ASID   CS RefCnt   Submitted    Completed\n");
 141                         seq_puts(s, "------------------------------------------------------\n");
 142                 }
 143                 seq_printf(s,
 144                         "   %llu       %d          %d           %d            %d\n",
 145                         cs->sequence, cs->ctx->asid,
 146                         kref_read(&cs->refcount),
 147                         cs->submitted, cs->completed);
 148         }
 149 
 150         spin_unlock(&dev_entry->cs_spinlock);
 151 
 152         if (!first)
 153                 seq_puts(s, "\n");
 154 
 155         return 0;
 156 }
 157 
 158 static int command_submission_jobs_show(struct seq_file *s, void *data)
 159 {
 160         struct hl_debugfs_entry *entry = s->private;
 161         struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
 162         struct hl_cs_job *job;
 163         bool first = true;
 164 
 165         spin_lock(&dev_entry->cs_job_spinlock);
 166 
 167         list_for_each_entry(job, &dev_entry->cs_job_list, debugfs_list) {
 168                 if (first) {
 169                         first = false;
 170                         seq_puts(s, "\n");
 171                         seq_puts(s, " JOB ID   CS ID    CTX ASID   H/W Queue\n");
 172                         seq_puts(s, "---------------------------------------\n");
 173                 }
 174                 if (job->cs)
 175                         seq_printf(s,
 176                                 "    %02d       %llu         %d         %d\n",
 177                                 job->id, job->cs->sequence, job->cs->ctx->asid,
 178                                 job->hw_queue_id);
 179                 else
 180                         seq_printf(s,
 181                                 "    %02d       0         %d         %d\n",
 182                                 job->id, HL_KERNEL_ASID_ID, job->hw_queue_id);
 183         }
 184 
 185         spin_unlock(&dev_entry->cs_job_spinlock);
 186 
 187         if (!first)
 188                 seq_puts(s, "\n");
 189 
 190         return 0;
 191 }
 192 
 193 static int userptr_show(struct seq_file *s, void *data)
 194 {
 195         struct hl_debugfs_entry *entry = s->private;
 196         struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
 197         struct hl_userptr *userptr;
 198         char dma_dir[4][30] = {"DMA_BIDIRECTIONAL", "DMA_TO_DEVICE",
 199                                 "DMA_FROM_DEVICE", "DMA_NONE"};
 200         bool first = true;
 201 
 202         spin_lock(&dev_entry->userptr_spinlock);
 203 
 204         list_for_each_entry(userptr, &dev_entry->userptr_list, debugfs_list) {
 205                 if (first) {
 206                         first = false;
 207                         seq_puts(s, "\n");
 208                         seq_puts(s, " user virtual address     size             dma dir\n");
 209                         seq_puts(s, "----------------------------------------------------------\n");
 210                 }
 211                 seq_printf(s,
 212                         "    0x%-14llx      %-10u    %-30s\n",
 213                         userptr->addr, userptr->size, dma_dir[userptr->dir]);
 214         }
 215 
 216         spin_unlock(&dev_entry->userptr_spinlock);
 217 
 218         if (!first)
 219                 seq_puts(s, "\n");
 220 
 221         return 0;
 222 }
 223 
 224 static int vm_show(struct seq_file *s, void *data)
 225 {
 226         struct hl_debugfs_entry *entry = s->private;
 227         struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
 228         struct hl_ctx *ctx;
 229         struct hl_vm *vm;
 230         struct hl_vm_hash_node *hnode;
 231         struct hl_userptr *userptr;
 232         struct hl_vm_phys_pg_pack *phys_pg_pack = NULL;
 233         enum vm_type_t *vm_type;
 234         bool once = true;
 235         u64 j;
 236         int i;
 237 
 238         if (!dev_entry->hdev->mmu_enable)
 239                 return 0;
 240 
 241         spin_lock(&dev_entry->ctx_mem_hash_spinlock);
 242 
 243         list_for_each_entry(ctx, &dev_entry->ctx_mem_hash_list, debugfs_list) {
 244                 once = false;
 245                 seq_puts(s, "\n\n----------------------------------------------------");
 246                 seq_puts(s, "\n----------------------------------------------------\n\n");
 247                 seq_printf(s, "ctx asid: %u\n", ctx->asid);
 248 
 249                 seq_puts(s, "\nmappings:\n\n");
 250                 seq_puts(s, "    virtual address        size          handle\n");
 251                 seq_puts(s, "----------------------------------------------------\n");
 252                 mutex_lock(&ctx->mem_hash_lock);
 253                 hash_for_each(ctx->mem_hash, i, hnode, node) {
 254                         vm_type = hnode->ptr;
 255 
 256                         if (*vm_type == VM_TYPE_USERPTR) {
 257                                 userptr = hnode->ptr;
 258                                 seq_printf(s,
 259                                         "    0x%-14llx      %-10u\n",
 260                                         hnode->vaddr, userptr->size);
 261                         } else {
 262                                 phys_pg_pack = hnode->ptr;
 263                                 seq_printf(s,
 264                                         "    0x%-14llx      %-10llu       %-4u\n",
 265                                         hnode->vaddr, phys_pg_pack->total_size,
 266                                         phys_pg_pack->handle);
 267                         }
 268                 }
 269                 mutex_unlock(&ctx->mem_hash_lock);
 270 
 271                 vm = &ctx->hdev->vm;
 272                 spin_lock(&vm->idr_lock);
 273 
 274                 if (!idr_is_empty(&vm->phys_pg_pack_handles))
 275                         seq_puts(s, "\n\nallocations:\n");
 276 
 277                 idr_for_each_entry(&vm->phys_pg_pack_handles, phys_pg_pack, i) {
 278                         if (phys_pg_pack->asid != ctx->asid)
 279                                 continue;
 280 
 281                         seq_printf(s, "\nhandle: %u\n", phys_pg_pack->handle);
 282                         seq_printf(s, "page size: %u\n\n",
 283                                                 phys_pg_pack->page_size);
 284                         seq_puts(s, "   physical address\n");
 285                         seq_puts(s, "---------------------\n");
 286                         for (j = 0 ; j < phys_pg_pack->npages ; j++) {
 287                                 seq_printf(s, "    0x%-14llx\n",
 288                                                 phys_pg_pack->pages[j]);
 289                         }
 290                 }
 291                 spin_unlock(&vm->idr_lock);
 292 
 293         }
 294 
 295         spin_unlock(&dev_entry->ctx_mem_hash_spinlock);
 296 
 297         if (!once)
 298                 seq_puts(s, "\n");
 299 
 300         return 0;
 301 }
 302 
 303 /* these inline functions are copied from mmu.c */
 304 static inline u64 get_hop0_addr(struct hl_ctx *ctx)
 305 {
 306         return ctx->hdev->asic_prop.mmu_pgt_addr +
 307                         (ctx->asid * ctx->hdev->asic_prop.mmu_hop_table_size);
 308 }
 309 
 310 static inline u64 get_hop0_pte_addr(struct hl_ctx *ctx, u64 hop_addr,
 311                 u64 virt_addr)
 312 {
 313         return hop_addr + ctx->hdev->asic_prop.mmu_pte_size *
 314                         ((virt_addr & HOP0_MASK) >> HOP0_SHIFT);
 315 }
 316 
 317 static inline u64 get_hop1_pte_addr(struct hl_ctx *ctx, u64 hop_addr,
 318                 u64 virt_addr)
 319 {
 320         return hop_addr + ctx->hdev->asic_prop.mmu_pte_size *
 321                         ((virt_addr & HOP1_MASK) >> HOP1_SHIFT);
 322 }
 323 
 324 static inline u64 get_hop2_pte_addr(struct hl_ctx *ctx, u64 hop_addr,
 325                 u64 virt_addr)
 326 {
 327         return hop_addr + ctx->hdev->asic_prop.mmu_pte_size *
 328                         ((virt_addr & HOP2_MASK) >> HOP2_SHIFT);
 329 }
 330 
 331 static inline u64 get_hop3_pte_addr(struct hl_ctx *ctx, u64 hop_addr,
 332                 u64 virt_addr)
 333 {
 334         return hop_addr + ctx->hdev->asic_prop.mmu_pte_size *
 335                         ((virt_addr & HOP3_MASK) >> HOP3_SHIFT);
 336 }
 337 
 338 static inline u64 get_hop4_pte_addr(struct hl_ctx *ctx, u64 hop_addr,
 339                 u64 virt_addr)
 340 {
 341         return hop_addr + ctx->hdev->asic_prop.mmu_pte_size *
 342                         ((virt_addr & HOP4_MASK) >> HOP4_SHIFT);
 343 }
 344 
 345 static inline u64 get_next_hop_addr(u64 curr_pte)
 346 {
 347         if (curr_pte & PAGE_PRESENT_MASK)
 348                 return curr_pte & PHYS_ADDR_MASK;
 349         else
 350                 return ULLONG_MAX;
 351 }
 352 
 353 static int mmu_show(struct seq_file *s, void *data)
 354 {
 355         struct hl_debugfs_entry *entry = s->private;
 356         struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
 357         struct hl_device *hdev = dev_entry->hdev;
 358         struct hl_ctx *ctx;
 359 
 360         u64 hop0_addr = 0, hop0_pte_addr = 0, hop0_pte = 0,
 361                 hop1_addr = 0, hop1_pte_addr = 0, hop1_pte = 0,
 362                 hop2_addr = 0, hop2_pte_addr = 0, hop2_pte = 0,
 363                 hop3_addr = 0, hop3_pte_addr = 0, hop3_pte = 0,
 364                 hop4_addr = 0, hop4_pte_addr = 0, hop4_pte = 0,
 365                 virt_addr = dev_entry->mmu_addr;
 366 
 367         if (!hdev->mmu_enable)
 368                 return 0;
 369 
 370         if (dev_entry->mmu_asid == HL_KERNEL_ASID_ID)
 371                 ctx = hdev->kernel_ctx;
 372         else
 373                 ctx = hdev->compute_ctx;
 374 
 375         if (!ctx) {
 376                 dev_err(hdev->dev, "no ctx available\n");
 377                 return 0;
 378         }
 379 
 380         mutex_lock(&ctx->mmu_lock);
 381 
 382         /* the following lookup is copied from unmap() in mmu.c */
 383 
 384         hop0_addr = get_hop0_addr(ctx);
 385         hop0_pte_addr = get_hop0_pte_addr(ctx, hop0_addr, virt_addr);
 386         hop0_pte = hdev->asic_funcs->read_pte(hdev, hop0_pte_addr);
 387         hop1_addr = get_next_hop_addr(hop0_pte);
 388 
 389         if (hop1_addr == ULLONG_MAX)
 390                 goto not_mapped;
 391 
 392         hop1_pte_addr = get_hop1_pte_addr(ctx, hop1_addr, virt_addr);
 393         hop1_pte = hdev->asic_funcs->read_pte(hdev, hop1_pte_addr);
 394         hop2_addr = get_next_hop_addr(hop1_pte);
 395 
 396         if (hop2_addr == ULLONG_MAX)
 397                 goto not_mapped;
 398 
 399         hop2_pte_addr = get_hop2_pte_addr(ctx, hop2_addr, virt_addr);
 400         hop2_pte = hdev->asic_funcs->read_pte(hdev, hop2_pte_addr);
 401         hop3_addr = get_next_hop_addr(hop2_pte);
 402 
 403         if (hop3_addr == ULLONG_MAX)
 404                 goto not_mapped;
 405 
 406         hop3_pte_addr = get_hop3_pte_addr(ctx, hop3_addr, virt_addr);
 407         hop3_pte = hdev->asic_funcs->read_pte(hdev, hop3_pte_addr);
 408 
 409         if (!(hop3_pte & LAST_MASK)) {
 410                 hop4_addr = get_next_hop_addr(hop3_pte);
 411 
 412                 if (hop4_addr == ULLONG_MAX)
 413                         goto not_mapped;
 414 
 415                 hop4_pte_addr = get_hop4_pte_addr(ctx, hop4_addr, virt_addr);
 416                 hop4_pte = hdev->asic_funcs->read_pte(hdev, hop4_pte_addr);
 417                 if (!(hop4_pte & PAGE_PRESENT_MASK))
 418                         goto not_mapped;
 419         } else {
 420                 if (!(hop3_pte & PAGE_PRESENT_MASK))
 421                         goto not_mapped;
 422         }
 423 
 424         seq_printf(s, "asid: %u, virt_addr: 0x%llx\n",
 425                         dev_entry->mmu_asid, dev_entry->mmu_addr);
 426 
 427         seq_printf(s, "hop0_addr: 0x%llx\n", hop0_addr);
 428         seq_printf(s, "hop0_pte_addr: 0x%llx\n", hop0_pte_addr);
 429         seq_printf(s, "hop0_pte: 0x%llx\n", hop0_pte);
 430 
 431         seq_printf(s, "hop1_addr: 0x%llx\n", hop1_addr);
 432         seq_printf(s, "hop1_pte_addr: 0x%llx\n", hop1_pte_addr);
 433         seq_printf(s, "hop1_pte: 0x%llx\n", hop1_pte);
 434 
 435         seq_printf(s, "hop2_addr: 0x%llx\n", hop2_addr);
 436         seq_printf(s, "hop2_pte_addr: 0x%llx\n", hop2_pte_addr);
 437         seq_printf(s, "hop2_pte: 0x%llx\n", hop2_pte);
 438 
 439         seq_printf(s, "hop3_addr: 0x%llx\n", hop3_addr);
 440         seq_printf(s, "hop3_pte_addr: 0x%llx\n", hop3_pte_addr);
 441         seq_printf(s, "hop3_pte: 0x%llx\n", hop3_pte);
 442 
 443         if (!(hop3_pte & LAST_MASK)) {
 444                 seq_printf(s, "hop4_addr: 0x%llx\n", hop4_addr);
 445                 seq_printf(s, "hop4_pte_addr: 0x%llx\n", hop4_pte_addr);
 446                 seq_printf(s, "hop4_pte: 0x%llx\n", hop4_pte);
 447         }
 448 
 449         goto out;
 450 
 451 not_mapped:
 452         dev_err(hdev->dev, "virt addr 0x%llx is not mapped to phys addr\n",
 453                         virt_addr);
 454 out:
 455         mutex_unlock(&ctx->mmu_lock);
 456 
 457         return 0;
 458 }
 459 
 460 static ssize_t mmu_write(struct file *file, const char __user *buf,
 461                 size_t count, loff_t *f_pos)
 462 {
 463         struct seq_file *s = file->private_data;
 464         struct hl_debugfs_entry *entry = s->private;
 465         struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
 466         struct hl_device *hdev = dev_entry->hdev;
 467         char kbuf[MMU_KBUF_SIZE];
 468         char *c;
 469         ssize_t rc;
 470 
 471         if (!hdev->mmu_enable)
 472                 return count;
 473 
 474         if (count > sizeof(kbuf) - 1)
 475                 goto err;
 476         if (copy_from_user(kbuf, buf, count))
 477                 goto err;
 478         kbuf[count] = 0;
 479 
 480         c = strchr(kbuf, ' ');
 481         if (!c)
 482                 goto err;
 483         *c = '\0';
 484 
 485         rc = kstrtouint(kbuf, 10, &dev_entry->mmu_asid);
 486         if (rc)
 487                 goto err;
 488 
 489         if (strncmp(c+1, "0x", 2))
 490                 goto err;
 491         rc = kstrtoull(c+3, 16, &dev_entry->mmu_addr);
 492         if (rc)
 493                 goto err;
 494 
 495         return count;
 496 
 497 err:
 498         dev_err(hdev->dev, "usage: echo <asid> <0xaddr> > mmu\n");
 499 
 500         return -EINVAL;
 501 }
 502 
 503 static int engines_show(struct seq_file *s, void *data)
 504 {
 505         struct hl_debugfs_entry *entry = s->private;
 506         struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
 507         struct hl_device *hdev = dev_entry->hdev;
 508 
 509         hdev->asic_funcs->is_device_idle(hdev, NULL, s);
 510 
 511         return 0;
 512 }
 513 
 514 static bool hl_is_device_va(struct hl_device *hdev, u64 addr)
 515 {
 516         struct asic_fixed_properties *prop = &hdev->asic_prop;
 517 
 518         if (!hdev->mmu_enable)
 519                 goto out;
 520 
 521         if (hdev->dram_supports_virtual_memory &&
 522                         addr >= prop->va_space_dram_start_address &&
 523                         addr < prop->va_space_dram_end_address)
 524                 return true;
 525 
 526         if (addr >= prop->va_space_host_start_address &&
 527                         addr < prop->va_space_host_end_address)
 528                 return true;
 529 out:
 530         return false;
 531 }
 532 
 533 static int device_va_to_pa(struct hl_device *hdev, u64 virt_addr,
 534                                 u64 *phys_addr)
 535 {
 536         struct hl_ctx *ctx = hdev->compute_ctx;
 537         u64 hop_addr, hop_pte_addr, hop_pte;
 538         u64 offset_mask = HOP4_MASK | OFFSET_MASK;
 539         int rc = 0;
 540 
 541         if (!ctx) {
 542                 dev_err(hdev->dev, "no ctx available\n");
 543                 return -EINVAL;
 544         }
 545 
 546         mutex_lock(&ctx->mmu_lock);
 547 
 548         /* hop 0 */
 549         hop_addr = get_hop0_addr(ctx);
 550         hop_pte_addr = get_hop0_pte_addr(ctx, hop_addr, virt_addr);
 551         hop_pte = hdev->asic_funcs->read_pte(hdev, hop_pte_addr);
 552 
 553         /* hop 1 */
 554         hop_addr = get_next_hop_addr(hop_pte);
 555         if (hop_addr == ULLONG_MAX)
 556                 goto not_mapped;
 557         hop_pte_addr = get_hop1_pte_addr(ctx, hop_addr, virt_addr);
 558         hop_pte = hdev->asic_funcs->read_pte(hdev, hop_pte_addr);
 559 
 560         /* hop 2 */
 561         hop_addr = get_next_hop_addr(hop_pte);
 562         if (hop_addr == ULLONG_MAX)
 563                 goto not_mapped;
 564         hop_pte_addr = get_hop2_pte_addr(ctx, hop_addr, virt_addr);
 565         hop_pte = hdev->asic_funcs->read_pte(hdev, hop_pte_addr);
 566 
 567         /* hop 3 */
 568         hop_addr = get_next_hop_addr(hop_pte);
 569         if (hop_addr == ULLONG_MAX)
 570                 goto not_mapped;
 571         hop_pte_addr = get_hop3_pte_addr(ctx, hop_addr, virt_addr);
 572         hop_pte = hdev->asic_funcs->read_pte(hdev, hop_pte_addr);
 573 
 574         if (!(hop_pte & LAST_MASK)) {
 575                 /* hop 4 */
 576                 hop_addr = get_next_hop_addr(hop_pte);
 577                 if (hop_addr == ULLONG_MAX)
 578                         goto not_mapped;
 579                 hop_pte_addr = get_hop4_pte_addr(ctx, hop_addr, virt_addr);
 580                 hop_pte = hdev->asic_funcs->read_pte(hdev, hop_pte_addr);
 581 
 582                 offset_mask = OFFSET_MASK;
 583         }
 584 
 585         if (!(hop_pte & PAGE_PRESENT_MASK))
 586                 goto not_mapped;
 587 
 588         *phys_addr = (hop_pte & ~offset_mask) | (virt_addr & offset_mask);
 589 
 590         goto out;
 591 
 592 not_mapped:
 593         dev_err(hdev->dev, "virt addr 0x%llx is not mapped to phys addr\n",
 594                         virt_addr);
 595         rc = -EINVAL;
 596 out:
 597         mutex_unlock(&ctx->mmu_lock);
 598         return rc;
 599 }
 600 
 601 static ssize_t hl_data_read32(struct file *f, char __user *buf,
 602                                         size_t count, loff_t *ppos)
 603 {
 604         struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 605         struct hl_device *hdev = entry->hdev;
 606         char tmp_buf[32];
 607         u64 addr = entry->addr;
 608         u32 val;
 609         ssize_t rc;
 610 
 611         if (*ppos)
 612                 return 0;
 613 
 614         if (hl_is_device_va(hdev, addr)) {
 615                 rc = device_va_to_pa(hdev, addr, &addr);
 616                 if (rc)
 617                         return rc;
 618         }
 619 
 620         rc = hdev->asic_funcs->debugfs_read32(hdev, addr, &val);
 621         if (rc) {
 622                 dev_err(hdev->dev, "Failed to read from 0x%010llx\n", addr);
 623                 return rc;
 624         }
 625 
 626         sprintf(tmp_buf, "0x%08x\n", val);
 627         return simple_read_from_buffer(buf, count, ppos, tmp_buf,
 628                         strlen(tmp_buf));
 629 }
 630 
 631 static ssize_t hl_data_write32(struct file *f, const char __user *buf,
 632                                         size_t count, loff_t *ppos)
 633 {
 634         struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 635         struct hl_device *hdev = entry->hdev;
 636         u64 addr = entry->addr;
 637         u32 value;
 638         ssize_t rc;
 639 
 640         rc = kstrtouint_from_user(buf, count, 16, &value);
 641         if (rc)
 642                 return rc;
 643 
 644         if (hl_is_device_va(hdev, addr)) {
 645                 rc = device_va_to_pa(hdev, addr, &addr);
 646                 if (rc)
 647                         return rc;
 648         }
 649 
 650         rc = hdev->asic_funcs->debugfs_write32(hdev, addr, value);
 651         if (rc) {
 652                 dev_err(hdev->dev, "Failed to write 0x%08x to 0x%010llx\n",
 653                         value, addr);
 654                 return rc;
 655         }
 656 
 657         return count;
 658 }
 659 
 660 static ssize_t hl_get_power_state(struct file *f, char __user *buf,
 661                 size_t count, loff_t *ppos)
 662 {
 663         struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 664         struct hl_device *hdev = entry->hdev;
 665         char tmp_buf[200];
 666         int i;
 667 
 668         if (*ppos)
 669                 return 0;
 670 
 671         if (hdev->pdev->current_state == PCI_D0)
 672                 i = 1;
 673         else if (hdev->pdev->current_state == PCI_D3hot)
 674                 i = 2;
 675         else
 676                 i = 3;
 677 
 678         sprintf(tmp_buf,
 679                 "current power state: %d\n1 - D0\n2 - D3hot\n3 - Unknown\n", i);
 680         return simple_read_from_buffer(buf, count, ppos, tmp_buf,
 681                         strlen(tmp_buf));
 682 }
 683 
 684 static ssize_t hl_set_power_state(struct file *f, const char __user *buf,
 685                                         size_t count, loff_t *ppos)
 686 {
 687         struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 688         struct hl_device *hdev = entry->hdev;
 689         u32 value;
 690         ssize_t rc;
 691 
 692         rc = kstrtouint_from_user(buf, count, 10, &value);
 693         if (rc)
 694                 return rc;
 695 
 696         if (value == 1) {
 697                 pci_set_power_state(hdev->pdev, PCI_D0);
 698                 pci_restore_state(hdev->pdev);
 699                 rc = pci_enable_device(hdev->pdev);
 700         } else if (value == 2) {
 701                 pci_save_state(hdev->pdev);
 702                 pci_disable_device(hdev->pdev);
 703                 pci_set_power_state(hdev->pdev, PCI_D3hot);
 704         } else {
 705                 dev_dbg(hdev->dev, "invalid power state value %u\n", value);
 706                 return -EINVAL;
 707         }
 708 
 709         return count;
 710 }
 711 
 712 static ssize_t hl_i2c_data_read(struct file *f, char __user *buf,
 713                                         size_t count, loff_t *ppos)
 714 {
 715         struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 716         struct hl_device *hdev = entry->hdev;
 717         char tmp_buf[32];
 718         u32 val;
 719         ssize_t rc;
 720 
 721         if (*ppos)
 722                 return 0;
 723 
 724         rc = hl_debugfs_i2c_read(hdev, entry->i2c_bus, entry->i2c_addr,
 725                         entry->i2c_reg, &val);
 726         if (rc) {
 727                 dev_err(hdev->dev,
 728                         "Failed to read from I2C bus %d, addr %d, reg %d\n",
 729                         entry->i2c_bus, entry->i2c_addr, entry->i2c_reg);
 730                 return rc;
 731         }
 732 
 733         sprintf(tmp_buf, "0x%02x\n", val);
 734         rc = simple_read_from_buffer(buf, count, ppos, tmp_buf,
 735                         strlen(tmp_buf));
 736 
 737         return rc;
 738 }
 739 
 740 static ssize_t hl_i2c_data_write(struct file *f, const char __user *buf,
 741                                         size_t count, loff_t *ppos)
 742 {
 743         struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 744         struct hl_device *hdev = entry->hdev;
 745         u32 value;
 746         ssize_t rc;
 747 
 748         rc = kstrtouint_from_user(buf, count, 16, &value);
 749         if (rc)
 750                 return rc;
 751 
 752         rc = hl_debugfs_i2c_write(hdev, entry->i2c_bus, entry->i2c_addr,
 753                         entry->i2c_reg, value);
 754         if (rc) {
 755                 dev_err(hdev->dev,
 756                         "Failed to write 0x%02x to I2C bus %d, addr %d, reg %d\n",
 757                         value, entry->i2c_bus, entry->i2c_addr, entry->i2c_reg);
 758                 return rc;
 759         }
 760 
 761         return count;
 762 }
 763 
 764 static ssize_t hl_led0_write(struct file *f, const char __user *buf,
 765                                         size_t count, loff_t *ppos)
 766 {
 767         struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 768         struct hl_device *hdev = entry->hdev;
 769         u32 value;
 770         ssize_t rc;
 771 
 772         rc = kstrtouint_from_user(buf, count, 10, &value);
 773         if (rc)
 774                 return rc;
 775 
 776         value = value ? 1 : 0;
 777 
 778         hl_debugfs_led_set(hdev, 0, value);
 779 
 780         return count;
 781 }
 782 
 783 static ssize_t hl_led1_write(struct file *f, const char __user *buf,
 784                                         size_t count, loff_t *ppos)
 785 {
 786         struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 787         struct hl_device *hdev = entry->hdev;
 788         u32 value;
 789         ssize_t rc;
 790 
 791         rc = kstrtouint_from_user(buf, count, 10, &value);
 792         if (rc)
 793                 return rc;
 794 
 795         value = value ? 1 : 0;
 796 
 797         hl_debugfs_led_set(hdev, 1, value);
 798 
 799         return count;
 800 }
 801 
 802 static ssize_t hl_led2_write(struct file *f, const char __user *buf,
 803                                         size_t count, loff_t *ppos)
 804 {
 805         struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 806         struct hl_device *hdev = entry->hdev;
 807         u32 value;
 808         ssize_t rc;
 809 
 810         rc = kstrtouint_from_user(buf, count, 10, &value);
 811         if (rc)
 812                 return rc;
 813 
 814         value = value ? 1 : 0;
 815 
 816         hl_debugfs_led_set(hdev, 2, value);
 817 
 818         return count;
 819 }
 820 
 821 static ssize_t hl_device_read(struct file *f, char __user *buf,
 822                                         size_t count, loff_t *ppos)
 823 {
 824         static const char *help =
 825                 "Valid values: disable, enable, suspend, resume, cpu_timeout\n";
 826         return simple_read_from_buffer(buf, count, ppos, help, strlen(help));
 827 }
 828 
 829 static ssize_t hl_device_write(struct file *f, const char __user *buf,
 830                                      size_t count, loff_t *ppos)
 831 {
 832         struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 833         struct hl_device *hdev = entry->hdev;
 834         char data[30] = {0};
 835 
 836         /* don't allow partial writes */
 837         if (*ppos != 0)
 838                 return 0;
 839 
 840         simple_write_to_buffer(data, 29, ppos, buf, count);
 841 
 842         if (strncmp("disable", data, strlen("disable")) == 0) {
 843                 hdev->disabled = true;
 844         } else if (strncmp("enable", data, strlen("enable")) == 0) {
 845                 hdev->disabled = false;
 846         } else if (strncmp("suspend", data, strlen("suspend")) == 0) {
 847                 hdev->asic_funcs->suspend(hdev);
 848         } else if (strncmp("resume", data, strlen("resume")) == 0) {
 849                 hdev->asic_funcs->resume(hdev);
 850         } else if (strncmp("cpu_timeout", data, strlen("cpu_timeout")) == 0) {
 851                 hdev->device_cpu_disabled = true;
 852         } else {
 853                 dev_err(hdev->dev,
 854                         "Valid values: disable, enable, suspend, resume, cpu_timeout\n");
 855                 count = -EINVAL;
 856         }
 857 
 858         return count;
 859 }
 860 
 861 static const struct file_operations hl_data32b_fops = {
 862         .owner = THIS_MODULE,
 863         .read = hl_data_read32,
 864         .write = hl_data_write32
 865 };
 866 
 867 static const struct file_operations hl_i2c_data_fops = {
 868         .owner = THIS_MODULE,
 869         .read = hl_i2c_data_read,
 870         .write = hl_i2c_data_write
 871 };
 872 
 873 static const struct file_operations hl_power_fops = {
 874         .owner = THIS_MODULE,
 875         .read = hl_get_power_state,
 876         .write = hl_set_power_state
 877 };
 878 
 879 static const struct file_operations hl_led0_fops = {
 880         .owner = THIS_MODULE,
 881         .write = hl_led0_write
 882 };
 883 
 884 static const struct file_operations hl_led1_fops = {
 885         .owner = THIS_MODULE,
 886         .write = hl_led1_write
 887 };
 888 
 889 static const struct file_operations hl_led2_fops = {
 890         .owner = THIS_MODULE,
 891         .write = hl_led2_write
 892 };
 893 
 894 static const struct file_operations hl_device_fops = {
 895         .owner = THIS_MODULE,
 896         .read = hl_device_read,
 897         .write = hl_device_write
 898 };
 899 
 900 static const struct hl_info_list hl_debugfs_list[] = {
 901         {"command_buffers", command_buffers_show, NULL},
 902         {"command_submission", command_submission_show, NULL},
 903         {"command_submission_jobs", command_submission_jobs_show, NULL},
 904         {"userptr", userptr_show, NULL},
 905         {"vm", vm_show, NULL},
 906         {"mmu", mmu_show, mmu_write},
 907         {"engines", engines_show, NULL}
 908 };
 909 
 910 static int hl_debugfs_open(struct inode *inode, struct file *file)
 911 {
 912         struct hl_debugfs_entry *node = inode->i_private;
 913 
 914         return single_open(file, node->info_ent->show, node);
 915 }
 916 
 917 static ssize_t hl_debugfs_write(struct file *file, const char __user *buf,
 918                 size_t count, loff_t *f_pos)
 919 {
 920         struct hl_debugfs_entry *node = file->f_inode->i_private;
 921 
 922         if (node->info_ent->write)
 923                 return node->info_ent->write(file, buf, count, f_pos);
 924         else
 925                 return -EINVAL;
 926 
 927 }
 928 
 929 static const struct file_operations hl_debugfs_fops = {
 930         .owner = THIS_MODULE,
 931         .open = hl_debugfs_open,
 932         .read = seq_read,
 933         .write = hl_debugfs_write,
 934         .llseek = seq_lseek,
 935         .release = single_release,
 936 };
 937 
 938 void hl_debugfs_add_device(struct hl_device *hdev)
 939 {
 940         struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
 941         int count = ARRAY_SIZE(hl_debugfs_list);
 942         struct hl_debugfs_entry *entry;
 943         struct dentry *ent;
 944         int i;
 945 
 946         dev_entry->hdev = hdev;
 947         dev_entry->entry_arr = kmalloc_array(count,
 948                                         sizeof(struct hl_debugfs_entry),
 949                                         GFP_KERNEL);
 950         if (!dev_entry->entry_arr)
 951                 return;
 952 
 953         INIT_LIST_HEAD(&dev_entry->file_list);
 954         INIT_LIST_HEAD(&dev_entry->cb_list);
 955         INIT_LIST_HEAD(&dev_entry->cs_list);
 956         INIT_LIST_HEAD(&dev_entry->cs_job_list);
 957         INIT_LIST_HEAD(&dev_entry->userptr_list);
 958         INIT_LIST_HEAD(&dev_entry->ctx_mem_hash_list);
 959         mutex_init(&dev_entry->file_mutex);
 960         spin_lock_init(&dev_entry->cb_spinlock);
 961         spin_lock_init(&dev_entry->cs_spinlock);
 962         spin_lock_init(&dev_entry->cs_job_spinlock);
 963         spin_lock_init(&dev_entry->userptr_spinlock);
 964         spin_lock_init(&dev_entry->ctx_mem_hash_spinlock);
 965 
 966         dev_entry->root = debugfs_create_dir(dev_name(hdev->dev),
 967                                                 hl_debug_root);
 968 
 969         debugfs_create_x64("addr",
 970                                 0644,
 971                                 dev_entry->root,
 972                                 &dev_entry->addr);
 973 
 974         debugfs_create_file("data32",
 975                                 0644,
 976                                 dev_entry->root,
 977                                 dev_entry,
 978                                 &hl_data32b_fops);
 979 
 980         debugfs_create_file("set_power_state",
 981                                 0200,
 982                                 dev_entry->root,
 983                                 dev_entry,
 984                                 &hl_power_fops);
 985 
 986         debugfs_create_u8("i2c_bus",
 987                                 0644,
 988                                 dev_entry->root,
 989                                 &dev_entry->i2c_bus);
 990 
 991         debugfs_create_u8("i2c_addr",
 992                                 0644,
 993                                 dev_entry->root,
 994                                 &dev_entry->i2c_addr);
 995 
 996         debugfs_create_u8("i2c_reg",
 997                                 0644,
 998                                 dev_entry->root,
 999                                 &dev_entry->i2c_reg);
1000 
1001         debugfs_create_file("i2c_data",
1002                                 0644,
1003                                 dev_entry->root,
1004                                 dev_entry,
1005                                 &hl_i2c_data_fops);
1006 
1007         debugfs_create_file("led0",
1008                                 0200,
1009                                 dev_entry->root,
1010                                 dev_entry,
1011                                 &hl_led0_fops);
1012 
1013         debugfs_create_file("led1",
1014                                 0200,
1015                                 dev_entry->root,
1016                                 dev_entry,
1017                                 &hl_led1_fops);
1018 
1019         debugfs_create_file("led2",
1020                                 0200,
1021                                 dev_entry->root,
1022                                 dev_entry,
1023                                 &hl_led2_fops);
1024 
1025         debugfs_create_file("device",
1026                                 0200,
1027                                 dev_entry->root,
1028                                 dev_entry,
1029                                 &hl_device_fops);
1030 
1031         for (i = 0, entry = dev_entry->entry_arr ; i < count ; i++, entry++) {
1032 
1033                 ent = debugfs_create_file(hl_debugfs_list[i].name,
1034                                         0444,
1035                                         dev_entry->root,
1036                                         entry,
1037                                         &hl_debugfs_fops);
1038                 entry->dent = ent;
1039                 entry->info_ent = &hl_debugfs_list[i];
1040                 entry->dev_entry = dev_entry;
1041         }
1042 }
1043 
1044 void hl_debugfs_remove_device(struct hl_device *hdev)
1045 {
1046         struct hl_dbg_device_entry *entry = &hdev->hl_debugfs;
1047 
1048         debugfs_remove_recursive(entry->root);
1049 
1050         mutex_destroy(&entry->file_mutex);
1051         kfree(entry->entry_arr);
1052 }
1053 
1054 void hl_debugfs_add_file(struct hl_fpriv *hpriv)
1055 {
1056         struct hl_dbg_device_entry *dev_entry = &hpriv->hdev->hl_debugfs;
1057 
1058         mutex_lock(&dev_entry->file_mutex);
1059         list_add(&hpriv->debugfs_list, &dev_entry->file_list);
1060         mutex_unlock(&dev_entry->file_mutex);
1061 }
1062 
1063 void hl_debugfs_remove_file(struct hl_fpriv *hpriv)
1064 {
1065         struct hl_dbg_device_entry *dev_entry = &hpriv->hdev->hl_debugfs;
1066 
1067         mutex_lock(&dev_entry->file_mutex);
1068         list_del(&hpriv->debugfs_list);
1069         mutex_unlock(&dev_entry->file_mutex);
1070 }
1071 
1072 void hl_debugfs_add_cb(struct hl_cb *cb)
1073 {
1074         struct hl_dbg_device_entry *dev_entry = &cb->hdev->hl_debugfs;
1075 
1076         spin_lock(&dev_entry->cb_spinlock);
1077         list_add(&cb->debugfs_list, &dev_entry->cb_list);
1078         spin_unlock(&dev_entry->cb_spinlock);
1079 }
1080 
1081 void hl_debugfs_remove_cb(struct hl_cb *cb)
1082 {
1083         struct hl_dbg_device_entry *dev_entry = &cb->hdev->hl_debugfs;
1084 
1085         spin_lock(&dev_entry->cb_spinlock);
1086         list_del(&cb->debugfs_list);
1087         spin_unlock(&dev_entry->cb_spinlock);
1088 }
1089 
1090 void hl_debugfs_add_cs(struct hl_cs *cs)
1091 {
1092         struct hl_dbg_device_entry *dev_entry = &cs->ctx->hdev->hl_debugfs;
1093 
1094         spin_lock(&dev_entry->cs_spinlock);
1095         list_add(&cs->debugfs_list, &dev_entry->cs_list);
1096         spin_unlock(&dev_entry->cs_spinlock);
1097 }
1098 
1099 void hl_debugfs_remove_cs(struct hl_cs *cs)
1100 {
1101         struct hl_dbg_device_entry *dev_entry = &cs->ctx->hdev->hl_debugfs;
1102 
1103         spin_lock(&dev_entry->cs_spinlock);
1104         list_del(&cs->debugfs_list);
1105         spin_unlock(&dev_entry->cs_spinlock);
1106 }
1107 
1108 void hl_debugfs_add_job(struct hl_device *hdev, struct hl_cs_job *job)
1109 {
1110         struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1111 
1112         spin_lock(&dev_entry->cs_job_spinlock);
1113         list_add(&job->debugfs_list, &dev_entry->cs_job_list);
1114         spin_unlock(&dev_entry->cs_job_spinlock);
1115 }
1116 
1117 void hl_debugfs_remove_job(struct hl_device *hdev, struct hl_cs_job *job)
1118 {
1119         struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1120 
1121         spin_lock(&dev_entry->cs_job_spinlock);
1122         list_del(&job->debugfs_list);
1123         spin_unlock(&dev_entry->cs_job_spinlock);
1124 }
1125 
1126 void hl_debugfs_add_userptr(struct hl_device *hdev, struct hl_userptr *userptr)
1127 {
1128         struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1129 
1130         spin_lock(&dev_entry->userptr_spinlock);
1131         list_add(&userptr->debugfs_list, &dev_entry->userptr_list);
1132         spin_unlock(&dev_entry->userptr_spinlock);
1133 }
1134 
1135 void hl_debugfs_remove_userptr(struct hl_device *hdev,
1136                                 struct hl_userptr *userptr)
1137 {
1138         struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1139 
1140         spin_lock(&dev_entry->userptr_spinlock);
1141         list_del(&userptr->debugfs_list);
1142         spin_unlock(&dev_entry->userptr_spinlock);
1143 }
1144 
1145 void hl_debugfs_add_ctx_mem_hash(struct hl_device *hdev, struct hl_ctx *ctx)
1146 {
1147         struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1148 
1149         spin_lock(&dev_entry->ctx_mem_hash_spinlock);
1150         list_add(&ctx->debugfs_list, &dev_entry->ctx_mem_hash_list);
1151         spin_unlock(&dev_entry->ctx_mem_hash_spinlock);
1152 }
1153 
1154 void hl_debugfs_remove_ctx_mem_hash(struct hl_device *hdev, struct hl_ctx *ctx)
1155 {
1156         struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1157 
1158         spin_lock(&dev_entry->ctx_mem_hash_spinlock);
1159         list_del(&ctx->debugfs_list);
1160         spin_unlock(&dev_entry->ctx_mem_hash_spinlock);
1161 }
1162 
1163 void __init hl_debugfs_init(void)
1164 {
1165         hl_debug_root = debugfs_create_dir("habanalabs", NULL);
1166 }
1167 
1168 void hl_debugfs_fini(void)
1169 {
1170         debugfs_remove_recursive(hl_debug_root);
1171 }

/* [<][>][^][v][top][bottom][index][help] */