linux/drivers/misc/habanalabs/common/debugfs.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2
   3/*
   4 * Copyright 2016-2021 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/uaccess.h>
  13#include <linux/vmalloc.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#define I2C_MAX_TRANSACTION_LEN 8
  19
  20static struct dentry *hl_debug_root;
  21
  22static int hl_debugfs_i2c_read(struct hl_device *hdev, u8 i2c_bus, u8 i2c_addr,
  23                                u8 i2c_reg, u8 i2c_len, u64 *val)
  24{
  25        struct cpucp_packet pkt;
  26        int rc;
  27
  28        if (!hl_device_operational(hdev, NULL))
  29                return -EBUSY;
  30
  31        if (i2c_len > I2C_MAX_TRANSACTION_LEN) {
  32                dev_err(hdev->dev, "I2C transaction length %u, exceeds maximum of %u\n",
  33                                i2c_len, I2C_MAX_TRANSACTION_LEN);
  34                return -EINVAL;
  35        }
  36
  37        memset(&pkt, 0, sizeof(pkt));
  38
  39        pkt.ctl = cpu_to_le32(CPUCP_PACKET_I2C_RD <<
  40                                CPUCP_PKT_CTL_OPCODE_SHIFT);
  41        pkt.i2c_bus = i2c_bus;
  42        pkt.i2c_addr = i2c_addr;
  43        pkt.i2c_reg = i2c_reg;
  44        pkt.i2c_len = i2c_len;
  45
  46        rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
  47                                                0, val);
  48        if (rc)
  49                dev_err(hdev->dev, "Failed to read from I2C, error %d\n", rc);
  50
  51        return rc;
  52}
  53
  54static int hl_debugfs_i2c_write(struct hl_device *hdev, u8 i2c_bus, u8 i2c_addr,
  55                                u8 i2c_reg, u8 i2c_len, u64 val)
  56{
  57        struct cpucp_packet pkt;
  58        int rc;
  59
  60        if (!hl_device_operational(hdev, NULL))
  61                return -EBUSY;
  62
  63        if (i2c_len > I2C_MAX_TRANSACTION_LEN) {
  64                dev_err(hdev->dev, "I2C transaction length %u, exceeds maximum of %u\n",
  65                                i2c_len, I2C_MAX_TRANSACTION_LEN);
  66                return -EINVAL;
  67        }
  68
  69        memset(&pkt, 0, sizeof(pkt));
  70
  71        pkt.ctl = cpu_to_le32(CPUCP_PACKET_I2C_WR <<
  72                                CPUCP_PKT_CTL_OPCODE_SHIFT);
  73        pkt.i2c_bus = i2c_bus;
  74        pkt.i2c_addr = i2c_addr;
  75        pkt.i2c_reg = i2c_reg;
  76        pkt.i2c_len = i2c_len;
  77        pkt.value = cpu_to_le64(val);
  78
  79        rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
  80                                                0, NULL);
  81
  82        if (rc)
  83                dev_err(hdev->dev, "Failed to write to I2C, error %d\n", rc);
  84
  85        return rc;
  86}
  87
  88static void hl_debugfs_led_set(struct hl_device *hdev, u8 led, u8 state)
  89{
  90        struct cpucp_packet pkt;
  91        int rc;
  92
  93        if (!hl_device_operational(hdev, NULL))
  94                return;
  95
  96        memset(&pkt, 0, sizeof(pkt));
  97
  98        pkt.ctl = cpu_to_le32(CPUCP_PACKET_LED_SET <<
  99                                CPUCP_PKT_CTL_OPCODE_SHIFT);
 100        pkt.led_index = cpu_to_le32(led);
 101        pkt.value = cpu_to_le64(state);
 102
 103        rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
 104                                                0, NULL);
 105
 106        if (rc)
 107                dev_err(hdev->dev, "Failed to set LED %d, error %d\n", led, rc);
 108}
 109
 110static int command_buffers_show(struct seq_file *s, void *data)
 111{
 112        struct hl_debugfs_entry *entry = s->private;
 113        struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
 114        struct hl_cb *cb;
 115        bool first = true;
 116
 117        spin_lock(&dev_entry->cb_spinlock);
 118
 119        list_for_each_entry(cb, &dev_entry->cb_list, debugfs_list) {
 120                if (first) {
 121                        first = false;
 122                        seq_puts(s, "\n");
 123                        seq_puts(s, " CB ID   CTX ID   CB size    CB RefCnt    mmap?   CS counter\n");
 124                        seq_puts(s, "---------------------------------------------------------------\n");
 125                }
 126                seq_printf(s,
 127                        "   %03llu        %d    0x%08x      %d          %d          %d\n",
 128                        cb->id, cb->ctx->asid, cb->size,
 129                        kref_read(&cb->refcount),
 130                        cb->mmap, atomic_read(&cb->cs_cnt));
 131        }
 132
 133        spin_unlock(&dev_entry->cb_spinlock);
 134
 135        if (!first)
 136                seq_puts(s, "\n");
 137
 138        return 0;
 139}
 140
 141static int command_submission_show(struct seq_file *s, void *data)
 142{
 143        struct hl_debugfs_entry *entry = s->private;
 144        struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
 145        struct hl_cs *cs;
 146        bool first = true;
 147
 148        spin_lock(&dev_entry->cs_spinlock);
 149
 150        list_for_each_entry(cs, &dev_entry->cs_list, debugfs_list) {
 151                if (first) {
 152                        first = false;
 153                        seq_puts(s, "\n");
 154                        seq_puts(s, " CS ID   CTX ASID   CS RefCnt   Submitted    Completed\n");
 155                        seq_puts(s, "------------------------------------------------------\n");
 156                }
 157                seq_printf(s,
 158                        "   %llu       %d          %d           %d            %d\n",
 159                        cs->sequence, cs->ctx->asid,
 160                        kref_read(&cs->refcount),
 161                        cs->submitted, cs->completed);
 162        }
 163
 164        spin_unlock(&dev_entry->cs_spinlock);
 165
 166        if (!first)
 167                seq_puts(s, "\n");
 168
 169        return 0;
 170}
 171
 172static int command_submission_jobs_show(struct seq_file *s, void *data)
 173{
 174        struct hl_debugfs_entry *entry = s->private;
 175        struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
 176        struct hl_cs_job *job;
 177        bool first = true;
 178
 179        spin_lock(&dev_entry->cs_job_spinlock);
 180
 181        list_for_each_entry(job, &dev_entry->cs_job_list, debugfs_list) {
 182                if (first) {
 183                        first = false;
 184                        seq_puts(s, "\n");
 185                        seq_puts(s, " JOB ID   CS ID    CTX ASID   JOB RefCnt   H/W Queue\n");
 186                        seq_puts(s, "----------------------------------------------------\n");
 187                }
 188                if (job->cs)
 189                        seq_printf(s,
 190                                "   %02d      %llu        %d          %d           %d\n",
 191                                job->id, job->cs->sequence, job->cs->ctx->asid,
 192                                kref_read(&job->refcount), job->hw_queue_id);
 193                else
 194                        seq_printf(s,
 195                                "   %02d      0        %d          %d           %d\n",
 196                                job->id, HL_KERNEL_ASID_ID,
 197                                kref_read(&job->refcount), job->hw_queue_id);
 198        }
 199
 200        spin_unlock(&dev_entry->cs_job_spinlock);
 201
 202        if (!first)
 203                seq_puts(s, "\n");
 204
 205        return 0;
 206}
 207
 208static int userptr_show(struct seq_file *s, void *data)
 209{
 210        struct hl_debugfs_entry *entry = s->private;
 211        struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
 212        struct hl_userptr *userptr;
 213        char dma_dir[4][30] = {"DMA_BIDIRECTIONAL", "DMA_TO_DEVICE",
 214                                "DMA_FROM_DEVICE", "DMA_NONE"};
 215        bool first = true;
 216
 217        spin_lock(&dev_entry->userptr_spinlock);
 218
 219        list_for_each_entry(userptr, &dev_entry->userptr_list, debugfs_list) {
 220                if (first) {
 221                        first = false;
 222                        seq_puts(s, "\n");
 223                        seq_puts(s, " pid      user virtual address     size             dma dir\n");
 224                        seq_puts(s, "----------------------------------------------------------\n");
 225                }
 226                seq_printf(s, " %-7d  0x%-14llx      %-10llu    %-30s\n",
 227                                userptr->pid, userptr->addr, userptr->size,
 228                                dma_dir[userptr->dir]);
 229        }
 230
 231        spin_unlock(&dev_entry->userptr_spinlock);
 232
 233        if (!first)
 234                seq_puts(s, "\n");
 235
 236        return 0;
 237}
 238
 239static int vm_show(struct seq_file *s, void *data)
 240{
 241        struct hl_debugfs_entry *entry = s->private;
 242        struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
 243        struct hl_vm_hw_block_list_node *lnode;
 244        struct hl_ctx *ctx;
 245        struct hl_vm *vm;
 246        struct hl_vm_hash_node *hnode;
 247        struct hl_userptr *userptr;
 248        struct hl_vm_phys_pg_pack *phys_pg_pack = NULL;
 249        struct hl_va_range *va_range;
 250        struct hl_vm_va_block *va_block;
 251        enum vm_type *vm_type;
 252        bool once = true;
 253        u64 j;
 254        int i;
 255
 256        if (!dev_entry->hdev->mmu_enable)
 257                return 0;
 258
 259        spin_lock(&dev_entry->ctx_mem_hash_spinlock);
 260
 261        list_for_each_entry(ctx, &dev_entry->ctx_mem_hash_list, debugfs_list) {
 262                once = false;
 263                seq_puts(s, "\n\n----------------------------------------------------");
 264                seq_puts(s, "\n----------------------------------------------------\n\n");
 265                seq_printf(s, "ctx asid: %u\n", ctx->asid);
 266
 267                seq_puts(s, "\nmappings:\n\n");
 268                seq_puts(s, "    virtual address        size          handle\n");
 269                seq_puts(s, "----------------------------------------------------\n");
 270                mutex_lock(&ctx->mem_hash_lock);
 271                hash_for_each(ctx->mem_hash, i, hnode, node) {
 272                        vm_type = hnode->ptr;
 273
 274                        if (*vm_type == VM_TYPE_USERPTR) {
 275                                userptr = hnode->ptr;
 276                                seq_printf(s,
 277                                        "    0x%-14llx      %-10llu\n",
 278                                        hnode->vaddr, userptr->size);
 279                        } else {
 280                                phys_pg_pack = hnode->ptr;
 281                                seq_printf(s,
 282                                        "    0x%-14llx      %-10llu       %-4u\n",
 283                                        hnode->vaddr, phys_pg_pack->total_size,
 284                                        phys_pg_pack->handle);
 285                        }
 286                }
 287                mutex_unlock(&ctx->mem_hash_lock);
 288
 289                if (ctx->asid != HL_KERNEL_ASID_ID &&
 290                    !list_empty(&ctx->hw_block_mem_list)) {
 291                        seq_puts(s, "\nhw_block mappings:\n\n");
 292                        seq_puts(s, "    virtual address    size    HW block id\n");
 293                        seq_puts(s, "-------------------------------------------\n");
 294                        mutex_lock(&ctx->hw_block_list_lock);
 295                        list_for_each_entry(lnode, &ctx->hw_block_mem_list,
 296                                            node) {
 297                                seq_printf(s,
 298                                        "    0x%-14lx   %-6u      %-9u\n",
 299                                        lnode->vaddr, lnode->size, lnode->id);
 300                        }
 301                        mutex_unlock(&ctx->hw_block_list_lock);
 302                }
 303
 304                vm = &ctx->hdev->vm;
 305                spin_lock(&vm->idr_lock);
 306
 307                if (!idr_is_empty(&vm->phys_pg_pack_handles))
 308                        seq_puts(s, "\n\nallocations:\n");
 309
 310                idr_for_each_entry(&vm->phys_pg_pack_handles, phys_pg_pack, i) {
 311                        if (phys_pg_pack->asid != ctx->asid)
 312                                continue;
 313
 314                        seq_printf(s, "\nhandle: %u\n", phys_pg_pack->handle);
 315                        seq_printf(s, "page size: %u\n\n",
 316                                                phys_pg_pack->page_size);
 317                        seq_puts(s, "   physical address\n");
 318                        seq_puts(s, "---------------------\n");
 319                        for (j = 0 ; j < phys_pg_pack->npages ; j++) {
 320                                seq_printf(s, "    0x%-14llx\n",
 321                                                phys_pg_pack->pages[j]);
 322                        }
 323                }
 324                spin_unlock(&vm->idr_lock);
 325
 326        }
 327
 328        spin_unlock(&dev_entry->ctx_mem_hash_spinlock);
 329
 330        ctx = hl_get_compute_ctx(dev_entry->hdev);
 331        if (ctx) {
 332                seq_puts(s, "\nVA ranges:\n\n");
 333                for (i = HL_VA_RANGE_TYPE_HOST ; i < HL_VA_RANGE_TYPE_MAX ; ++i) {
 334                        va_range = ctx->va_range[i];
 335                        seq_printf(s, "   va_range %d\n", i);
 336                        seq_puts(s, "---------------------\n");
 337                        mutex_lock(&va_range->lock);
 338                        list_for_each_entry(va_block, &va_range->list, node) {
 339                                seq_printf(s, "%#16llx - %#16llx (%#llx)\n",
 340                                           va_block->start, va_block->end,
 341                                           va_block->size);
 342                        }
 343                        mutex_unlock(&va_range->lock);
 344                        seq_puts(s, "\n");
 345                }
 346                hl_ctx_put(ctx);
 347        }
 348
 349        if (!once)
 350                seq_puts(s, "\n");
 351
 352        return 0;
 353}
 354
 355static int userptr_lookup_show(struct seq_file *s, void *data)
 356{
 357        struct hl_debugfs_entry *entry = s->private;
 358        struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
 359        struct scatterlist *sg;
 360        struct hl_userptr *userptr;
 361        bool first = true;
 362        u64 total_npages, npages, sg_start, sg_end;
 363        dma_addr_t dma_addr;
 364        int i;
 365
 366        spin_lock(&dev_entry->userptr_spinlock);
 367
 368        list_for_each_entry(userptr, &dev_entry->userptr_list, debugfs_list) {
 369                if (dev_entry->userptr_lookup >= userptr->addr &&
 370                dev_entry->userptr_lookup < userptr->addr + userptr->size) {
 371                        total_npages = 0;
 372                        for_each_sg(userptr->sgt->sgl, sg, userptr->sgt->nents,
 373                                        i) {
 374                                npages = hl_get_sg_info(sg, &dma_addr);
 375                                sg_start = userptr->addr +
 376                                        total_npages * PAGE_SIZE;
 377                                sg_end = userptr->addr +
 378                                        (total_npages + npages) * PAGE_SIZE;
 379
 380                                if (dev_entry->userptr_lookup >= sg_start &&
 381                                    dev_entry->userptr_lookup < sg_end) {
 382                                        dma_addr += (dev_entry->userptr_lookup -
 383                                                        sg_start);
 384                                        if (first) {
 385                                                first = false;
 386                                                seq_puts(s, "\n");
 387                                                seq_puts(s, " user virtual address         dma address       pid        region start     region size\n");
 388                                                seq_puts(s, "---------------------------------------------------------------------------------------\n");
 389                                        }
 390                                        seq_printf(s, " 0x%-18llx  0x%-16llx  %-8u  0x%-16llx %-12llu\n",
 391                                                dev_entry->userptr_lookup,
 392                                                (u64)dma_addr, userptr->pid,
 393                                                userptr->addr, userptr->size);
 394                                }
 395                                total_npages += npages;
 396                        }
 397                }
 398        }
 399
 400        spin_unlock(&dev_entry->userptr_spinlock);
 401
 402        if (!first)
 403                seq_puts(s, "\n");
 404
 405        return 0;
 406}
 407
 408static ssize_t userptr_lookup_write(struct file *file, const char __user *buf,
 409                size_t count, loff_t *f_pos)
 410{
 411        struct seq_file *s = file->private_data;
 412        struct hl_debugfs_entry *entry = s->private;
 413        struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
 414        ssize_t rc;
 415        u64 value;
 416
 417        rc = kstrtoull_from_user(buf, count, 16, &value);
 418        if (rc)
 419                return rc;
 420
 421        dev_entry->userptr_lookup = value;
 422
 423        return count;
 424}
 425
 426static int mmu_show(struct seq_file *s, void *data)
 427{
 428        struct hl_debugfs_entry *entry = s->private;
 429        struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
 430        struct hl_device *hdev = dev_entry->hdev;
 431        struct hl_ctx *ctx;
 432        struct hl_mmu_hop_info hops_info = {0};
 433        u64 virt_addr = dev_entry->mmu_addr, phys_addr;
 434        int i;
 435
 436        if (!hdev->mmu_enable)
 437                return 0;
 438
 439        if (dev_entry->mmu_asid == HL_KERNEL_ASID_ID)
 440                ctx = hdev->kernel_ctx;
 441        else
 442                ctx = hl_get_compute_ctx(hdev);
 443
 444        if (!ctx) {
 445                dev_err(hdev->dev, "no ctx available\n");
 446                return 0;
 447        }
 448
 449        if (hl_mmu_get_tlb_info(ctx, virt_addr, &hops_info)) {
 450                dev_err(hdev->dev, "virt addr 0x%llx is not mapped to phys addr\n",
 451                                virt_addr);
 452                return 0;
 453        }
 454
 455        hl_mmu_va_to_pa(ctx, virt_addr, &phys_addr);
 456
 457        if (hops_info.scrambled_vaddr &&
 458                (dev_entry->mmu_addr != hops_info.scrambled_vaddr))
 459                seq_printf(s,
 460                        "asid: %u, virt_addr: 0x%llx, scrambled virt_addr: 0x%llx,\nphys_addr: 0x%llx, scrambled_phys_addr: 0x%llx\n",
 461                        dev_entry->mmu_asid, dev_entry->mmu_addr,
 462                        hops_info.scrambled_vaddr,
 463                        hops_info.unscrambled_paddr, phys_addr);
 464        else
 465                seq_printf(s,
 466                        "asid: %u, virt_addr: 0x%llx, phys_addr: 0x%llx\n",
 467                        dev_entry->mmu_asid, dev_entry->mmu_addr, phys_addr);
 468
 469        for (i = 0 ; i < hops_info.used_hops ; i++) {
 470                seq_printf(s, "hop%d_addr: 0x%llx\n",
 471                                i, hops_info.hop_info[i].hop_addr);
 472                seq_printf(s, "hop%d_pte_addr: 0x%llx\n",
 473                                i, hops_info.hop_info[i].hop_pte_addr);
 474                seq_printf(s, "hop%d_pte: 0x%llx\n",
 475                                i, hops_info.hop_info[i].hop_pte_val);
 476        }
 477
 478        return 0;
 479}
 480
 481static ssize_t mmu_asid_va_write(struct file *file, const char __user *buf,
 482                size_t count, loff_t *f_pos)
 483{
 484        struct seq_file *s = file->private_data;
 485        struct hl_debugfs_entry *entry = s->private;
 486        struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
 487        struct hl_device *hdev = dev_entry->hdev;
 488        char kbuf[MMU_KBUF_SIZE];
 489        char *c;
 490        ssize_t rc;
 491
 492        if (!hdev->mmu_enable)
 493                return count;
 494
 495        if (count > sizeof(kbuf) - 1)
 496                goto err;
 497        if (copy_from_user(kbuf, buf, count))
 498                goto err;
 499        kbuf[count] = 0;
 500
 501        c = strchr(kbuf, ' ');
 502        if (!c)
 503                goto err;
 504        *c = '\0';
 505
 506        rc = kstrtouint(kbuf, 10, &dev_entry->mmu_asid);
 507        if (rc)
 508                goto err;
 509
 510        if (strncmp(c+1, "0x", 2))
 511                goto err;
 512        rc = kstrtoull(c+3, 16, &dev_entry->mmu_addr);
 513        if (rc)
 514                goto err;
 515
 516        return count;
 517
 518err:
 519        dev_err(hdev->dev, "usage: echo <asid> <0xaddr> > mmu\n");
 520
 521        return -EINVAL;
 522}
 523
 524static int engines_show(struct seq_file *s, void *data)
 525{
 526        struct hl_debugfs_entry *entry = s->private;
 527        struct hl_dbg_device_entry *dev_entry = entry->dev_entry;
 528        struct hl_device *hdev = dev_entry->hdev;
 529
 530        if (hdev->reset_info.in_reset) {
 531                dev_warn_ratelimited(hdev->dev,
 532                                "Can't check device idle during reset\n");
 533                return 0;
 534        }
 535
 536        hdev->asic_funcs->is_device_idle(hdev, NULL, 0, s);
 537
 538        return 0;
 539}
 540
 541static bool hl_is_device_va(struct hl_device *hdev, u64 addr)
 542{
 543        struct asic_fixed_properties *prop = &hdev->asic_prop;
 544
 545        if (!hdev->mmu_enable)
 546                goto out;
 547
 548        if (prop->dram_supports_virtual_memory &&
 549                (addr >= prop->dmmu.start_addr && addr < prop->dmmu.end_addr))
 550                return true;
 551
 552        if (addr >= prop->pmmu.start_addr &&
 553                addr < prop->pmmu.end_addr)
 554                return true;
 555
 556        if (addr >= prop->pmmu_huge.start_addr &&
 557                addr < prop->pmmu_huge.end_addr)
 558                return true;
 559out:
 560        return false;
 561}
 562
 563static bool hl_is_device_internal_memory_va(struct hl_device *hdev, u64 addr,
 564                                                u32 size)
 565{
 566        struct asic_fixed_properties *prop = &hdev->asic_prop;
 567        u64 dram_start_addr, dram_end_addr;
 568
 569        if (!hdev->mmu_enable)
 570                return false;
 571
 572        if (prop->dram_supports_virtual_memory) {
 573                dram_start_addr = prop->dmmu.start_addr;
 574                dram_end_addr = prop->dmmu.end_addr;
 575        } else {
 576                dram_start_addr = prop->dram_base_address;
 577                dram_end_addr = prop->dram_end_address;
 578        }
 579
 580        if (hl_mem_area_inside_range(addr, size, dram_start_addr,
 581                                        dram_end_addr))
 582                return true;
 583
 584        if (hl_mem_area_inside_range(addr, size, prop->sram_base_address,
 585                                        prop->sram_end_address))
 586                return true;
 587
 588        return false;
 589}
 590
 591static int device_va_to_pa(struct hl_device *hdev, u64 virt_addr, u32 size,
 592                        u64 *phys_addr)
 593{
 594        struct hl_vm_phys_pg_pack *phys_pg_pack;
 595        struct hl_ctx *ctx;
 596        struct hl_vm_hash_node *hnode;
 597        u64 end_address, range_size;
 598        struct hl_userptr *userptr;
 599        enum vm_type *vm_type;
 600        bool valid = false;
 601        int i, rc = 0;
 602
 603        ctx = hl_get_compute_ctx(hdev);
 604
 605        if (!ctx) {
 606                dev_err(hdev->dev, "no ctx available\n");
 607                return -EINVAL;
 608        }
 609
 610        /* Verify address is mapped */
 611        mutex_lock(&ctx->mem_hash_lock);
 612        hash_for_each(ctx->mem_hash, i, hnode, node) {
 613                vm_type = hnode->ptr;
 614
 615                if (*vm_type == VM_TYPE_USERPTR) {
 616                        userptr = hnode->ptr;
 617                        range_size = userptr->size;
 618                } else {
 619                        phys_pg_pack = hnode->ptr;
 620                        range_size = phys_pg_pack->total_size;
 621                }
 622
 623                end_address = virt_addr + size;
 624                if ((virt_addr >= hnode->vaddr) &&
 625                                (end_address <= hnode->vaddr + range_size)) {
 626                        valid = true;
 627                        break;
 628                }
 629        }
 630        mutex_unlock(&ctx->mem_hash_lock);
 631
 632        if (!valid) {
 633                dev_err(hdev->dev,
 634                        "virt addr 0x%llx is not mapped\n",
 635                        virt_addr);
 636                return -EINVAL;
 637        }
 638
 639        rc = hl_mmu_va_to_pa(ctx, virt_addr, phys_addr);
 640        if (rc) {
 641                dev_err(hdev->dev,
 642                        "virt addr 0x%llx is not mapped to phys addr\n",
 643                        virt_addr);
 644                rc = -EINVAL;
 645        }
 646
 647        return rc;
 648}
 649
 650static ssize_t hl_data_read32(struct file *f, char __user *buf,
 651                                        size_t count, loff_t *ppos)
 652{
 653        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 654        struct hl_device *hdev = entry->hdev;
 655        u64 addr = entry->addr;
 656        bool user_address;
 657        char tmp_buf[32];
 658        ssize_t rc;
 659        u32 val;
 660
 661        if (hdev->reset_info.in_reset) {
 662                dev_warn_ratelimited(hdev->dev, "Can't read during reset\n");
 663                return 0;
 664        }
 665
 666        if (*ppos)
 667                return 0;
 668
 669        user_address = hl_is_device_va(hdev, addr);
 670        if (user_address) {
 671                rc = device_va_to_pa(hdev, addr, sizeof(val), &addr);
 672                if (rc)
 673                        return rc;
 674        }
 675
 676        rc = hdev->asic_funcs->debugfs_read32(hdev, addr, user_address, &val);
 677        if (rc) {
 678                dev_err(hdev->dev, "Failed to read from 0x%010llx\n", addr);
 679                return rc;
 680        }
 681
 682        sprintf(tmp_buf, "0x%08x\n", val);
 683        return simple_read_from_buffer(buf, count, ppos, tmp_buf,
 684                        strlen(tmp_buf));
 685}
 686
 687static ssize_t hl_data_write32(struct file *f, const char __user *buf,
 688                                        size_t count, loff_t *ppos)
 689{
 690        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 691        struct hl_device *hdev = entry->hdev;
 692        u64 addr = entry->addr;
 693        bool user_address;
 694        u32 value;
 695        ssize_t rc;
 696
 697        if (hdev->reset_info.in_reset) {
 698                dev_warn_ratelimited(hdev->dev, "Can't write during reset\n");
 699                return 0;
 700        }
 701
 702        rc = kstrtouint_from_user(buf, count, 16, &value);
 703        if (rc)
 704                return rc;
 705
 706        user_address = hl_is_device_va(hdev, addr);
 707        if (user_address) {
 708                rc = device_va_to_pa(hdev, addr, sizeof(value), &addr);
 709                if (rc)
 710                        return rc;
 711        }
 712
 713        rc = hdev->asic_funcs->debugfs_write32(hdev, addr, user_address, value);
 714        if (rc) {
 715                dev_err(hdev->dev, "Failed to write 0x%08x to 0x%010llx\n",
 716                        value, addr);
 717                return rc;
 718        }
 719
 720        return count;
 721}
 722
 723static ssize_t hl_data_read64(struct file *f, char __user *buf,
 724                                        size_t count, loff_t *ppos)
 725{
 726        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 727        struct hl_device *hdev = entry->hdev;
 728        u64 addr = entry->addr;
 729        bool user_address;
 730        char tmp_buf[32];
 731        ssize_t rc;
 732        u64 val;
 733
 734        if (hdev->reset_info.in_reset) {
 735                dev_warn_ratelimited(hdev->dev, "Can't read during reset\n");
 736                return 0;
 737        }
 738
 739        if (*ppos)
 740                return 0;
 741
 742        user_address = hl_is_device_va(hdev, addr);
 743        if (user_address) {
 744                rc = device_va_to_pa(hdev, addr, sizeof(val), &addr);
 745                if (rc)
 746                        return rc;
 747        }
 748
 749        rc = hdev->asic_funcs->debugfs_read64(hdev, addr, user_address, &val);
 750        if (rc) {
 751                dev_err(hdev->dev, "Failed to read from 0x%010llx\n", addr);
 752                return rc;
 753        }
 754
 755        sprintf(tmp_buf, "0x%016llx\n", val);
 756        return simple_read_from_buffer(buf, count, ppos, tmp_buf,
 757                        strlen(tmp_buf));
 758}
 759
 760static ssize_t hl_data_write64(struct file *f, const char __user *buf,
 761                                        size_t count, loff_t *ppos)
 762{
 763        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 764        struct hl_device *hdev = entry->hdev;
 765        u64 addr = entry->addr;
 766        bool user_address;
 767        u64 value;
 768        ssize_t rc;
 769
 770        if (hdev->reset_info.in_reset) {
 771                dev_warn_ratelimited(hdev->dev, "Can't write during reset\n");
 772                return 0;
 773        }
 774
 775        rc = kstrtoull_from_user(buf, count, 16, &value);
 776        if (rc)
 777                return rc;
 778
 779        user_address = hl_is_device_va(hdev, addr);
 780        if (user_address) {
 781                rc = device_va_to_pa(hdev, addr, sizeof(value), &addr);
 782                if (rc)
 783                        return rc;
 784        }
 785
 786        rc = hdev->asic_funcs->debugfs_write64(hdev, addr, user_address, value);
 787        if (rc) {
 788                dev_err(hdev->dev, "Failed to write 0x%016llx to 0x%010llx\n",
 789                        value, addr);
 790                return rc;
 791        }
 792
 793        return count;
 794}
 795
 796static ssize_t hl_dma_size_write(struct file *f, const char __user *buf,
 797                                        size_t count, loff_t *ppos)
 798{
 799        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 800        struct hl_device *hdev = entry->hdev;
 801        u64 addr = entry->addr;
 802        ssize_t rc;
 803        u32 size;
 804
 805        if (hdev->reset_info.in_reset) {
 806                dev_warn_ratelimited(hdev->dev, "Can't DMA during reset\n");
 807                return 0;
 808        }
 809        rc = kstrtouint_from_user(buf, count, 16, &size);
 810        if (rc)
 811                return rc;
 812
 813        if (!size) {
 814                dev_err(hdev->dev, "DMA read failed. size can't be 0\n");
 815                return -EINVAL;
 816        }
 817
 818        if (size > SZ_128M) {
 819                dev_err(hdev->dev,
 820                        "DMA read failed. size can't be larger than 128MB\n");
 821                return -EINVAL;
 822        }
 823
 824        if (!hl_is_device_internal_memory_va(hdev, addr, size)) {
 825                dev_err(hdev->dev,
 826                        "DMA read failed. Invalid 0x%010llx + 0x%08x\n",
 827                        addr, size);
 828                return -EINVAL;
 829        }
 830
 831        /* Free the previous allocation, if there was any */
 832        entry->blob_desc.size = 0;
 833        vfree(entry->blob_desc.data);
 834
 835        entry->blob_desc.data = vmalloc(size);
 836        if (!entry->blob_desc.data)
 837                return -ENOMEM;
 838
 839        rc = hdev->asic_funcs->debugfs_read_dma(hdev, addr, size,
 840                                                entry->blob_desc.data);
 841        if (rc) {
 842                dev_err(hdev->dev, "Failed to DMA from 0x%010llx\n", addr);
 843                vfree(entry->blob_desc.data);
 844                entry->blob_desc.data = NULL;
 845                return -EIO;
 846        }
 847
 848        entry->blob_desc.size = size;
 849
 850        return count;
 851}
 852
 853static ssize_t hl_get_power_state(struct file *f, char __user *buf,
 854                size_t count, loff_t *ppos)
 855{
 856        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 857        struct hl_device *hdev = entry->hdev;
 858        char tmp_buf[200];
 859        int i;
 860
 861        if (*ppos)
 862                return 0;
 863
 864        if (hdev->pdev->current_state == PCI_D0)
 865                i = 1;
 866        else if (hdev->pdev->current_state == PCI_D3hot)
 867                i = 2;
 868        else
 869                i = 3;
 870
 871        sprintf(tmp_buf,
 872                "current power state: %d\n1 - D0\n2 - D3hot\n3 - Unknown\n", i);
 873        return simple_read_from_buffer(buf, count, ppos, tmp_buf,
 874                        strlen(tmp_buf));
 875}
 876
 877static ssize_t hl_set_power_state(struct file *f, const char __user *buf,
 878                                        size_t count, loff_t *ppos)
 879{
 880        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 881        struct hl_device *hdev = entry->hdev;
 882        u32 value;
 883        ssize_t rc;
 884
 885        rc = kstrtouint_from_user(buf, count, 10, &value);
 886        if (rc)
 887                return rc;
 888
 889        if (value == 1) {
 890                pci_set_power_state(hdev->pdev, PCI_D0);
 891                pci_restore_state(hdev->pdev);
 892                rc = pci_enable_device(hdev->pdev);
 893                if (rc < 0)
 894                        return rc;
 895        } else if (value == 2) {
 896                pci_save_state(hdev->pdev);
 897                pci_disable_device(hdev->pdev);
 898                pci_set_power_state(hdev->pdev, PCI_D3hot);
 899        } else {
 900                dev_dbg(hdev->dev, "invalid power state value %u\n", value);
 901                return -EINVAL;
 902        }
 903
 904        return count;
 905}
 906
 907static ssize_t hl_i2c_data_read(struct file *f, char __user *buf,
 908                                        size_t count, loff_t *ppos)
 909{
 910        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 911        struct hl_device *hdev = entry->hdev;
 912        char tmp_buf[32];
 913        u64 val;
 914        ssize_t rc;
 915
 916        if (*ppos)
 917                return 0;
 918
 919        rc = hl_debugfs_i2c_read(hdev, entry->i2c_bus, entry->i2c_addr,
 920                        entry->i2c_reg, entry->i2c_len, &val);
 921        if (rc) {
 922                dev_err(hdev->dev,
 923                        "Failed to read from I2C bus %d, addr %d, reg %d, len %d\n",
 924                        entry->i2c_bus, entry->i2c_addr, entry->i2c_reg, entry->i2c_len);
 925                return rc;
 926        }
 927
 928        sprintf(tmp_buf, "%#02llx\n", val);
 929        rc = simple_read_from_buffer(buf, count, ppos, tmp_buf,
 930                        strlen(tmp_buf));
 931
 932        return rc;
 933}
 934
 935static ssize_t hl_i2c_data_write(struct file *f, const char __user *buf,
 936                                        size_t count, loff_t *ppos)
 937{
 938        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 939        struct hl_device *hdev = entry->hdev;
 940        u64 value;
 941        ssize_t rc;
 942
 943        rc = kstrtou64_from_user(buf, count, 16, &value);
 944        if (rc)
 945                return rc;
 946
 947        rc = hl_debugfs_i2c_write(hdev, entry->i2c_bus, entry->i2c_addr,
 948                        entry->i2c_reg, entry->i2c_len, value);
 949        if (rc) {
 950                dev_err(hdev->dev,
 951                        "Failed to write %#02llx to I2C bus %d, addr %d, reg %d, len %d\n",
 952                        value, entry->i2c_bus, entry->i2c_addr, entry->i2c_reg, entry->i2c_len);
 953                return rc;
 954        }
 955
 956        return count;
 957}
 958
 959static ssize_t hl_led0_write(struct file *f, const char __user *buf,
 960                                        size_t count, loff_t *ppos)
 961{
 962        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 963        struct hl_device *hdev = entry->hdev;
 964        u32 value;
 965        ssize_t rc;
 966
 967        rc = kstrtouint_from_user(buf, count, 10, &value);
 968        if (rc)
 969                return rc;
 970
 971        value = value ? 1 : 0;
 972
 973        hl_debugfs_led_set(hdev, 0, value);
 974
 975        return count;
 976}
 977
 978static ssize_t hl_led1_write(struct file *f, const char __user *buf,
 979                                        size_t count, loff_t *ppos)
 980{
 981        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
 982        struct hl_device *hdev = entry->hdev;
 983        u32 value;
 984        ssize_t rc;
 985
 986        rc = kstrtouint_from_user(buf, count, 10, &value);
 987        if (rc)
 988                return rc;
 989
 990        value = value ? 1 : 0;
 991
 992        hl_debugfs_led_set(hdev, 1, value);
 993
 994        return count;
 995}
 996
 997static ssize_t hl_led2_write(struct file *f, const char __user *buf,
 998                                        size_t count, loff_t *ppos)
 999{
1000        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
1001        struct hl_device *hdev = entry->hdev;
1002        u32 value;
1003        ssize_t rc;
1004
1005        rc = kstrtouint_from_user(buf, count, 10, &value);
1006        if (rc)
1007                return rc;
1008
1009        value = value ? 1 : 0;
1010
1011        hl_debugfs_led_set(hdev, 2, value);
1012
1013        return count;
1014}
1015
1016static ssize_t hl_device_read(struct file *f, char __user *buf,
1017                                        size_t count, loff_t *ppos)
1018{
1019        static const char *help =
1020                "Valid values: disable, enable, suspend, resume, cpu_timeout\n";
1021        return simple_read_from_buffer(buf, count, ppos, help, strlen(help));
1022}
1023
1024static ssize_t hl_device_write(struct file *f, const char __user *buf,
1025                                     size_t count, loff_t *ppos)
1026{
1027        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
1028        struct hl_device *hdev = entry->hdev;
1029        char data[30] = {0};
1030
1031        /* don't allow partial writes */
1032        if (*ppos != 0)
1033                return 0;
1034
1035        simple_write_to_buffer(data, 29, ppos, buf, count);
1036
1037        if (strncmp("disable", data, strlen("disable")) == 0) {
1038                hdev->disabled = true;
1039        } else if (strncmp("enable", data, strlen("enable")) == 0) {
1040                hdev->disabled = false;
1041        } else if (strncmp("suspend", data, strlen("suspend")) == 0) {
1042                hdev->asic_funcs->suspend(hdev);
1043        } else if (strncmp("resume", data, strlen("resume")) == 0) {
1044                hdev->asic_funcs->resume(hdev);
1045        } else if (strncmp("cpu_timeout", data, strlen("cpu_timeout")) == 0) {
1046                hdev->device_cpu_disabled = true;
1047        } else {
1048                dev_err(hdev->dev,
1049                        "Valid values: disable, enable, suspend, resume, cpu_timeout\n");
1050                count = -EINVAL;
1051        }
1052
1053        return count;
1054}
1055
1056static ssize_t hl_clk_gate_read(struct file *f, char __user *buf,
1057                                        size_t count, loff_t *ppos)
1058{
1059        return 0;
1060}
1061
1062static ssize_t hl_clk_gate_write(struct file *f, const char __user *buf,
1063                                     size_t count, loff_t *ppos)
1064{
1065        return count;
1066}
1067
1068static ssize_t hl_stop_on_err_read(struct file *f, char __user *buf,
1069                                        size_t count, loff_t *ppos)
1070{
1071        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
1072        struct hl_device *hdev = entry->hdev;
1073        char tmp_buf[200];
1074        ssize_t rc;
1075
1076        if (!hdev->asic_prop.configurable_stop_on_err)
1077                return -EOPNOTSUPP;
1078
1079        if (*ppos)
1080                return 0;
1081
1082        sprintf(tmp_buf, "%d\n", hdev->stop_on_err);
1083        rc = simple_read_from_buffer(buf, strlen(tmp_buf) + 1, ppos, tmp_buf,
1084                        strlen(tmp_buf) + 1);
1085
1086        return rc;
1087}
1088
1089static ssize_t hl_stop_on_err_write(struct file *f, const char __user *buf,
1090                                     size_t count, loff_t *ppos)
1091{
1092        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
1093        struct hl_device *hdev = entry->hdev;
1094        u32 value;
1095        ssize_t rc;
1096
1097        if (!hdev->asic_prop.configurable_stop_on_err)
1098                return -EOPNOTSUPP;
1099
1100        if (hdev->reset_info.in_reset) {
1101                dev_warn_ratelimited(hdev->dev,
1102                                "Can't change stop on error during reset\n");
1103                return 0;
1104        }
1105
1106        rc = kstrtouint_from_user(buf, count, 10, &value);
1107        if (rc)
1108                return rc;
1109
1110        hdev->stop_on_err = value ? 1 : 0;
1111
1112        hl_device_reset(hdev, 0);
1113
1114        return count;
1115}
1116
1117static ssize_t hl_security_violations_read(struct file *f, char __user *buf,
1118                                        size_t count, loff_t *ppos)
1119{
1120        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
1121        struct hl_device *hdev = entry->hdev;
1122
1123        hdev->asic_funcs->ack_protection_bits_errors(hdev);
1124
1125        return 0;
1126}
1127
1128static ssize_t hl_state_dump_read(struct file *f, char __user *buf,
1129                                        size_t count, loff_t *ppos)
1130{
1131        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
1132        ssize_t rc;
1133
1134        down_read(&entry->state_dump_sem);
1135        if (!entry->state_dump[entry->state_dump_head])
1136                rc = 0;
1137        else
1138                rc = simple_read_from_buffer(
1139                        buf, count, ppos,
1140                        entry->state_dump[entry->state_dump_head],
1141                        strlen(entry->state_dump[entry->state_dump_head]));
1142        up_read(&entry->state_dump_sem);
1143
1144        return rc;
1145}
1146
1147static ssize_t hl_state_dump_write(struct file *f, const char __user *buf,
1148                                        size_t count, loff_t *ppos)
1149{
1150        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
1151        struct hl_device *hdev = entry->hdev;
1152        ssize_t rc;
1153        u32 size;
1154        int i;
1155
1156        rc = kstrtouint_from_user(buf, count, 10, &size);
1157        if (rc)
1158                return rc;
1159
1160        if (size <= 0 || size >= ARRAY_SIZE(entry->state_dump)) {
1161                dev_err(hdev->dev, "Invalid number of dumps to skip\n");
1162                return -EINVAL;
1163        }
1164
1165        if (entry->state_dump[entry->state_dump_head]) {
1166                down_write(&entry->state_dump_sem);
1167                for (i = 0; i < size; ++i) {
1168                        vfree(entry->state_dump[entry->state_dump_head]);
1169                        entry->state_dump[entry->state_dump_head] = NULL;
1170                        if (entry->state_dump_head > 0)
1171                                entry->state_dump_head--;
1172                        else
1173                                entry->state_dump_head =
1174                                        ARRAY_SIZE(entry->state_dump) - 1;
1175                }
1176                up_write(&entry->state_dump_sem);
1177        }
1178
1179        return count;
1180}
1181
1182static ssize_t hl_timeout_locked_read(struct file *f, char __user *buf,
1183                                        size_t count, loff_t *ppos)
1184{
1185        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
1186        struct hl_device *hdev = entry->hdev;
1187        char tmp_buf[200];
1188        ssize_t rc;
1189
1190        if (*ppos)
1191                return 0;
1192
1193        sprintf(tmp_buf, "%d\n",
1194                jiffies_to_msecs(hdev->timeout_jiffies) / 1000);
1195        rc = simple_read_from_buffer(buf, strlen(tmp_buf) + 1, ppos, tmp_buf,
1196                        strlen(tmp_buf) + 1);
1197
1198        return rc;
1199}
1200
1201static ssize_t hl_timeout_locked_write(struct file *f, const char __user *buf,
1202                                     size_t count, loff_t *ppos)
1203{
1204        struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
1205        struct hl_device *hdev = entry->hdev;
1206        u32 value;
1207        ssize_t rc;
1208
1209        rc = kstrtouint_from_user(buf, count, 10, &value);
1210        if (rc)
1211                return rc;
1212
1213        if (value)
1214                hdev->timeout_jiffies = msecs_to_jiffies(value * 1000);
1215        else
1216                hdev->timeout_jiffies = MAX_SCHEDULE_TIMEOUT;
1217
1218        return count;
1219}
1220
1221static const struct file_operations hl_data32b_fops = {
1222        .owner = THIS_MODULE,
1223        .read = hl_data_read32,
1224        .write = hl_data_write32
1225};
1226
1227static const struct file_operations hl_data64b_fops = {
1228        .owner = THIS_MODULE,
1229        .read = hl_data_read64,
1230        .write = hl_data_write64
1231};
1232
1233static const struct file_operations hl_dma_size_fops = {
1234        .owner = THIS_MODULE,
1235        .write = hl_dma_size_write
1236};
1237
1238static const struct file_operations hl_i2c_data_fops = {
1239        .owner = THIS_MODULE,
1240        .read = hl_i2c_data_read,
1241        .write = hl_i2c_data_write
1242};
1243
1244static const struct file_operations hl_power_fops = {
1245        .owner = THIS_MODULE,
1246        .read = hl_get_power_state,
1247        .write = hl_set_power_state
1248};
1249
1250static const struct file_operations hl_led0_fops = {
1251        .owner = THIS_MODULE,
1252        .write = hl_led0_write
1253};
1254
1255static const struct file_operations hl_led1_fops = {
1256        .owner = THIS_MODULE,
1257        .write = hl_led1_write
1258};
1259
1260static const struct file_operations hl_led2_fops = {
1261        .owner = THIS_MODULE,
1262        .write = hl_led2_write
1263};
1264
1265static const struct file_operations hl_device_fops = {
1266        .owner = THIS_MODULE,
1267        .read = hl_device_read,
1268        .write = hl_device_write
1269};
1270
1271static const struct file_operations hl_clk_gate_fops = {
1272        .owner = THIS_MODULE,
1273        .read = hl_clk_gate_read,
1274        .write = hl_clk_gate_write
1275};
1276
1277static const struct file_operations hl_stop_on_err_fops = {
1278        .owner = THIS_MODULE,
1279        .read = hl_stop_on_err_read,
1280        .write = hl_stop_on_err_write
1281};
1282
1283static const struct file_operations hl_security_violations_fops = {
1284        .owner = THIS_MODULE,
1285        .read = hl_security_violations_read
1286};
1287
1288static const struct file_operations hl_state_dump_fops = {
1289        .owner = THIS_MODULE,
1290        .read = hl_state_dump_read,
1291        .write = hl_state_dump_write
1292};
1293
1294static const struct file_operations hl_timeout_locked_fops = {
1295        .owner = THIS_MODULE,
1296        .read = hl_timeout_locked_read,
1297        .write = hl_timeout_locked_write
1298};
1299
1300static const struct hl_info_list hl_debugfs_list[] = {
1301        {"command_buffers", command_buffers_show, NULL},
1302        {"command_submission", command_submission_show, NULL},
1303        {"command_submission_jobs", command_submission_jobs_show, NULL},
1304        {"userptr", userptr_show, NULL},
1305        {"vm", vm_show, NULL},
1306        {"userptr_lookup", userptr_lookup_show, userptr_lookup_write},
1307        {"mmu", mmu_show, mmu_asid_va_write},
1308        {"engines", engines_show, NULL}
1309};
1310
1311static int hl_debugfs_open(struct inode *inode, struct file *file)
1312{
1313        struct hl_debugfs_entry *node = inode->i_private;
1314
1315        return single_open(file, node->info_ent->show, node);
1316}
1317
1318static ssize_t hl_debugfs_write(struct file *file, const char __user *buf,
1319                size_t count, loff_t *f_pos)
1320{
1321        struct hl_debugfs_entry *node = file->f_inode->i_private;
1322
1323        if (node->info_ent->write)
1324                return node->info_ent->write(file, buf, count, f_pos);
1325        else
1326                return -EINVAL;
1327
1328}
1329
1330static const struct file_operations hl_debugfs_fops = {
1331        .owner = THIS_MODULE,
1332        .open = hl_debugfs_open,
1333        .read = seq_read,
1334        .write = hl_debugfs_write,
1335        .llseek = seq_lseek,
1336        .release = single_release,
1337};
1338
1339void hl_debugfs_add_device(struct hl_device *hdev)
1340{
1341        struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1342        int count = ARRAY_SIZE(hl_debugfs_list);
1343        struct hl_debugfs_entry *entry;
1344        int i;
1345
1346        dev_entry->hdev = hdev;
1347        dev_entry->entry_arr = kmalloc_array(count,
1348                                        sizeof(struct hl_debugfs_entry),
1349                                        GFP_KERNEL);
1350        if (!dev_entry->entry_arr)
1351                return;
1352
1353        dev_entry->blob_desc.size = 0;
1354        dev_entry->blob_desc.data = NULL;
1355
1356        INIT_LIST_HEAD(&dev_entry->file_list);
1357        INIT_LIST_HEAD(&dev_entry->cb_list);
1358        INIT_LIST_HEAD(&dev_entry->cs_list);
1359        INIT_LIST_HEAD(&dev_entry->cs_job_list);
1360        INIT_LIST_HEAD(&dev_entry->userptr_list);
1361        INIT_LIST_HEAD(&dev_entry->ctx_mem_hash_list);
1362        mutex_init(&dev_entry->file_mutex);
1363        init_rwsem(&dev_entry->state_dump_sem);
1364        spin_lock_init(&dev_entry->cb_spinlock);
1365        spin_lock_init(&dev_entry->cs_spinlock);
1366        spin_lock_init(&dev_entry->cs_job_spinlock);
1367        spin_lock_init(&dev_entry->userptr_spinlock);
1368        spin_lock_init(&dev_entry->ctx_mem_hash_spinlock);
1369
1370        dev_entry->root = debugfs_create_dir(dev_name(hdev->dev),
1371                                                hl_debug_root);
1372
1373        debugfs_create_x64("addr",
1374                                0644,
1375                                dev_entry->root,
1376                                &dev_entry->addr);
1377
1378        debugfs_create_file("data32",
1379                                0644,
1380                                dev_entry->root,
1381                                dev_entry,
1382                                &hl_data32b_fops);
1383
1384        debugfs_create_file("data64",
1385                                0644,
1386                                dev_entry->root,
1387                                dev_entry,
1388                                &hl_data64b_fops);
1389
1390        debugfs_create_file("set_power_state",
1391                                0200,
1392                                dev_entry->root,
1393                                dev_entry,
1394                                &hl_power_fops);
1395
1396        debugfs_create_u8("i2c_bus",
1397                                0644,
1398                                dev_entry->root,
1399                                &dev_entry->i2c_bus);
1400
1401        debugfs_create_u8("i2c_addr",
1402                                0644,
1403                                dev_entry->root,
1404                                &dev_entry->i2c_addr);
1405
1406        debugfs_create_u8("i2c_reg",
1407                                0644,
1408                                dev_entry->root,
1409                                &dev_entry->i2c_reg);
1410
1411        debugfs_create_u8("i2c_len",
1412                                0644,
1413                                dev_entry->root,
1414                                &dev_entry->i2c_len);
1415
1416        debugfs_create_file("i2c_data",
1417                                0644,
1418                                dev_entry->root,
1419                                dev_entry,
1420                                &hl_i2c_data_fops);
1421
1422        debugfs_create_file("led0",
1423                                0200,
1424                                dev_entry->root,
1425                                dev_entry,
1426                                &hl_led0_fops);
1427
1428        debugfs_create_file("led1",
1429                                0200,
1430                                dev_entry->root,
1431                                dev_entry,
1432                                &hl_led1_fops);
1433
1434        debugfs_create_file("led2",
1435                                0200,
1436                                dev_entry->root,
1437                                dev_entry,
1438                                &hl_led2_fops);
1439
1440        debugfs_create_file("device",
1441                                0200,
1442                                dev_entry->root,
1443                                dev_entry,
1444                                &hl_device_fops);
1445
1446        debugfs_create_file("clk_gate",
1447                                0200,
1448                                dev_entry->root,
1449                                dev_entry,
1450                                &hl_clk_gate_fops);
1451
1452        debugfs_create_file("stop_on_err",
1453                                0644,
1454                                dev_entry->root,
1455                                dev_entry,
1456                                &hl_stop_on_err_fops);
1457
1458        debugfs_create_file("dump_security_violations",
1459                                0644,
1460                                dev_entry->root,
1461                                dev_entry,
1462                                &hl_security_violations_fops);
1463
1464        debugfs_create_file("dma_size",
1465                                0200,
1466                                dev_entry->root,
1467                                dev_entry,
1468                                &hl_dma_size_fops);
1469
1470        debugfs_create_blob("data_dma",
1471                                0400,
1472                                dev_entry->root,
1473                                &dev_entry->blob_desc);
1474
1475        debugfs_create_x8("skip_reset_on_timeout",
1476                                0644,
1477                                dev_entry->root,
1478                                &hdev->reset_info.skip_reset_on_timeout);
1479
1480        debugfs_create_file("state_dump",
1481                                0600,
1482                                dev_entry->root,
1483                                dev_entry,
1484                                &hl_state_dump_fops);
1485
1486        debugfs_create_file("timeout_locked",
1487                                0644,
1488                                dev_entry->root,
1489                                dev_entry,
1490                                &hl_timeout_locked_fops);
1491
1492        for (i = 0, entry = dev_entry->entry_arr ; i < count ; i++, entry++) {
1493                debugfs_create_file(hl_debugfs_list[i].name,
1494                                        0444,
1495                                        dev_entry->root,
1496                                        entry,
1497                                        &hl_debugfs_fops);
1498                entry->info_ent = &hl_debugfs_list[i];
1499                entry->dev_entry = dev_entry;
1500        }
1501}
1502
1503void hl_debugfs_remove_device(struct hl_device *hdev)
1504{
1505        struct hl_dbg_device_entry *entry = &hdev->hl_debugfs;
1506        int i;
1507
1508        debugfs_remove_recursive(entry->root);
1509
1510        mutex_destroy(&entry->file_mutex);
1511
1512        vfree(entry->blob_desc.data);
1513
1514        for (i = 0; i < ARRAY_SIZE(entry->state_dump); ++i)
1515                vfree(entry->state_dump[i]);
1516
1517        kfree(entry->entry_arr);
1518}
1519
1520void hl_debugfs_add_file(struct hl_fpriv *hpriv)
1521{
1522        struct hl_dbg_device_entry *dev_entry = &hpriv->hdev->hl_debugfs;
1523
1524        mutex_lock(&dev_entry->file_mutex);
1525        list_add(&hpriv->debugfs_list, &dev_entry->file_list);
1526        mutex_unlock(&dev_entry->file_mutex);
1527}
1528
1529void hl_debugfs_remove_file(struct hl_fpriv *hpriv)
1530{
1531        struct hl_dbg_device_entry *dev_entry = &hpriv->hdev->hl_debugfs;
1532
1533        mutex_lock(&dev_entry->file_mutex);
1534        list_del(&hpriv->debugfs_list);
1535        mutex_unlock(&dev_entry->file_mutex);
1536}
1537
1538void hl_debugfs_add_cb(struct hl_cb *cb)
1539{
1540        struct hl_dbg_device_entry *dev_entry = &cb->hdev->hl_debugfs;
1541
1542        spin_lock(&dev_entry->cb_spinlock);
1543        list_add(&cb->debugfs_list, &dev_entry->cb_list);
1544        spin_unlock(&dev_entry->cb_spinlock);
1545}
1546
1547void hl_debugfs_remove_cb(struct hl_cb *cb)
1548{
1549        struct hl_dbg_device_entry *dev_entry = &cb->hdev->hl_debugfs;
1550
1551        spin_lock(&dev_entry->cb_spinlock);
1552        list_del(&cb->debugfs_list);
1553        spin_unlock(&dev_entry->cb_spinlock);
1554}
1555
1556void hl_debugfs_add_cs(struct hl_cs *cs)
1557{
1558        struct hl_dbg_device_entry *dev_entry = &cs->ctx->hdev->hl_debugfs;
1559
1560        spin_lock(&dev_entry->cs_spinlock);
1561        list_add(&cs->debugfs_list, &dev_entry->cs_list);
1562        spin_unlock(&dev_entry->cs_spinlock);
1563}
1564
1565void hl_debugfs_remove_cs(struct hl_cs *cs)
1566{
1567        struct hl_dbg_device_entry *dev_entry = &cs->ctx->hdev->hl_debugfs;
1568
1569        spin_lock(&dev_entry->cs_spinlock);
1570        list_del(&cs->debugfs_list);
1571        spin_unlock(&dev_entry->cs_spinlock);
1572}
1573
1574void hl_debugfs_add_job(struct hl_device *hdev, struct hl_cs_job *job)
1575{
1576        struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1577
1578        spin_lock(&dev_entry->cs_job_spinlock);
1579        list_add(&job->debugfs_list, &dev_entry->cs_job_list);
1580        spin_unlock(&dev_entry->cs_job_spinlock);
1581}
1582
1583void hl_debugfs_remove_job(struct hl_device *hdev, struct hl_cs_job *job)
1584{
1585        struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1586
1587        spin_lock(&dev_entry->cs_job_spinlock);
1588        list_del(&job->debugfs_list);
1589        spin_unlock(&dev_entry->cs_job_spinlock);
1590}
1591
1592void hl_debugfs_add_userptr(struct hl_device *hdev, struct hl_userptr *userptr)
1593{
1594        struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1595
1596        spin_lock(&dev_entry->userptr_spinlock);
1597        list_add(&userptr->debugfs_list, &dev_entry->userptr_list);
1598        spin_unlock(&dev_entry->userptr_spinlock);
1599}
1600
1601void hl_debugfs_remove_userptr(struct hl_device *hdev,
1602                                struct hl_userptr *userptr)
1603{
1604        struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1605
1606        spin_lock(&dev_entry->userptr_spinlock);
1607        list_del(&userptr->debugfs_list);
1608        spin_unlock(&dev_entry->userptr_spinlock);
1609}
1610
1611void hl_debugfs_add_ctx_mem_hash(struct hl_device *hdev, struct hl_ctx *ctx)
1612{
1613        struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1614
1615        spin_lock(&dev_entry->ctx_mem_hash_spinlock);
1616        list_add(&ctx->debugfs_list, &dev_entry->ctx_mem_hash_list);
1617        spin_unlock(&dev_entry->ctx_mem_hash_spinlock);
1618}
1619
1620void hl_debugfs_remove_ctx_mem_hash(struct hl_device *hdev, struct hl_ctx *ctx)
1621{
1622        struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1623
1624        spin_lock(&dev_entry->ctx_mem_hash_spinlock);
1625        list_del(&ctx->debugfs_list);
1626        spin_unlock(&dev_entry->ctx_mem_hash_spinlock);
1627}
1628
1629/**
1630 * hl_debugfs_set_state_dump - register state dump making it accessible via
1631 *                             debugfs
1632 * @hdev: pointer to the device structure
1633 * @data: the actual dump data
1634 * @length: the length of the data
1635 */
1636void hl_debugfs_set_state_dump(struct hl_device *hdev, char *data,
1637                                        unsigned long length)
1638{
1639        struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs;
1640
1641        down_write(&dev_entry->state_dump_sem);
1642
1643        dev_entry->state_dump_head = (dev_entry->state_dump_head + 1) %
1644                                        ARRAY_SIZE(dev_entry->state_dump);
1645        vfree(dev_entry->state_dump[dev_entry->state_dump_head]);
1646        dev_entry->state_dump[dev_entry->state_dump_head] = data;
1647
1648        up_write(&dev_entry->state_dump_sem);
1649}
1650
1651void __init hl_debugfs_init(void)
1652{
1653        hl_debug_root = debugfs_create_dir("habanalabs", NULL);
1654}
1655
1656void hl_debugfs_fini(void)
1657{
1658        debugfs_remove_recursive(hl_debug_root);
1659}
1660