18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci 38c2ecf20Sopenharmony_ci/* 48c2ecf20Sopenharmony_ci * Copyright 2016-2019 HabanaLabs, Ltd. 58c2ecf20Sopenharmony_ci * All Rights Reserved. 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include "habanalabs.h" 98c2ecf20Sopenharmony_ci#include "../include/hw_ip/mmu/mmu_general.h" 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <linux/pci.h> 128c2ecf20Sopenharmony_ci#include <linux/debugfs.h> 138c2ecf20Sopenharmony_ci#include <linux/uaccess.h> 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#define MMU_ADDR_BUF_SIZE 40 168c2ecf20Sopenharmony_ci#define MMU_ASID_BUF_SIZE 10 178c2ecf20Sopenharmony_ci#define MMU_KBUF_SIZE (MMU_ADDR_BUF_SIZE + MMU_ASID_BUF_SIZE) 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_cistatic struct dentry *hl_debug_root; 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_cistatic int hl_debugfs_i2c_read(struct hl_device *hdev, u8 i2c_bus, u8 i2c_addr, 228c2ecf20Sopenharmony_ci u8 i2c_reg, long *val) 238c2ecf20Sopenharmony_ci{ 248c2ecf20Sopenharmony_ci struct cpucp_packet pkt; 258c2ecf20Sopenharmony_ci int rc; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci if (hl_device_disabled_or_in_reset(hdev)) 288c2ecf20Sopenharmony_ci return -EBUSY; 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci memset(&pkt, 0, sizeof(pkt)); 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci pkt.ctl = cpu_to_le32(CPUCP_PACKET_I2C_RD << 338c2ecf20Sopenharmony_ci CPUCP_PKT_CTL_OPCODE_SHIFT); 348c2ecf20Sopenharmony_ci pkt.i2c_bus = i2c_bus; 358c2ecf20Sopenharmony_ci pkt.i2c_addr = i2c_addr; 368c2ecf20Sopenharmony_ci pkt.i2c_reg = i2c_reg; 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), 398c2ecf20Sopenharmony_ci 0, val); 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci if (rc) 428c2ecf20Sopenharmony_ci dev_err(hdev->dev, "Failed to read from I2C, error %d\n", rc); 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci return rc; 458c2ecf20Sopenharmony_ci} 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_cistatic int hl_debugfs_i2c_write(struct hl_device *hdev, u8 i2c_bus, u8 i2c_addr, 488c2ecf20Sopenharmony_ci u8 i2c_reg, u32 val) 498c2ecf20Sopenharmony_ci{ 508c2ecf20Sopenharmony_ci struct cpucp_packet pkt; 518c2ecf20Sopenharmony_ci int rc; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci if (hl_device_disabled_or_in_reset(hdev)) 548c2ecf20Sopenharmony_ci return -EBUSY; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci memset(&pkt, 0, sizeof(pkt)); 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci pkt.ctl = cpu_to_le32(CPUCP_PACKET_I2C_WR << 598c2ecf20Sopenharmony_ci CPUCP_PKT_CTL_OPCODE_SHIFT); 608c2ecf20Sopenharmony_ci pkt.i2c_bus = i2c_bus; 618c2ecf20Sopenharmony_ci pkt.i2c_addr = i2c_addr; 628c2ecf20Sopenharmony_ci pkt.i2c_reg = i2c_reg; 638c2ecf20Sopenharmony_ci pkt.value = cpu_to_le64(val); 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), 668c2ecf20Sopenharmony_ci 0, NULL); 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci if (rc) 698c2ecf20Sopenharmony_ci dev_err(hdev->dev, "Failed to write to I2C, error %d\n", rc); 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci return rc; 728c2ecf20Sopenharmony_ci} 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_cistatic void hl_debugfs_led_set(struct hl_device *hdev, u8 led, u8 state) 758c2ecf20Sopenharmony_ci{ 768c2ecf20Sopenharmony_ci struct cpucp_packet pkt; 778c2ecf20Sopenharmony_ci int rc; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci if (hl_device_disabled_or_in_reset(hdev)) 808c2ecf20Sopenharmony_ci return; 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci memset(&pkt, 0, sizeof(pkt)); 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci pkt.ctl = cpu_to_le32(CPUCP_PACKET_LED_SET << 858c2ecf20Sopenharmony_ci CPUCP_PKT_CTL_OPCODE_SHIFT); 868c2ecf20Sopenharmony_ci pkt.led_index = cpu_to_le32(led); 878c2ecf20Sopenharmony_ci pkt.value = cpu_to_le64(state); 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), 908c2ecf20Sopenharmony_ci 0, NULL); 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci if (rc) 938c2ecf20Sopenharmony_ci dev_err(hdev->dev, "Failed to set LED %d, error %d\n", led, rc); 948c2ecf20Sopenharmony_ci} 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_cistatic int command_buffers_show(struct seq_file *s, void *data) 978c2ecf20Sopenharmony_ci{ 988c2ecf20Sopenharmony_ci struct hl_debugfs_entry *entry = s->private; 998c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *dev_entry = entry->dev_entry; 1008c2ecf20Sopenharmony_ci struct hl_cb *cb; 1018c2ecf20Sopenharmony_ci bool first = true; 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci spin_lock(&dev_entry->cb_spinlock); 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci list_for_each_entry(cb, &dev_entry->cb_list, debugfs_list) { 1068c2ecf20Sopenharmony_ci if (first) { 1078c2ecf20Sopenharmony_ci first = false; 1088c2ecf20Sopenharmony_ci seq_puts(s, "\n"); 1098c2ecf20Sopenharmony_ci seq_puts(s, " CB ID CTX ID CB size CB RefCnt mmap? CS counter\n"); 1108c2ecf20Sopenharmony_ci seq_puts(s, "---------------------------------------------------------------\n"); 1118c2ecf20Sopenharmony_ci } 1128c2ecf20Sopenharmony_ci seq_printf(s, 1138c2ecf20Sopenharmony_ci " %03llu %d 0x%08x %d %d %d\n", 1148c2ecf20Sopenharmony_ci cb->id, cb->ctx->asid, cb->size, 1158c2ecf20Sopenharmony_ci kref_read(&cb->refcount), 1168c2ecf20Sopenharmony_ci cb->mmap, cb->cs_cnt); 1178c2ecf20Sopenharmony_ci } 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci spin_unlock(&dev_entry->cb_spinlock); 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci if (!first) 1228c2ecf20Sopenharmony_ci seq_puts(s, "\n"); 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci return 0; 1258c2ecf20Sopenharmony_ci} 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_cistatic int command_submission_show(struct seq_file *s, void *data) 1288c2ecf20Sopenharmony_ci{ 1298c2ecf20Sopenharmony_ci struct hl_debugfs_entry *entry = s->private; 1308c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *dev_entry = entry->dev_entry; 1318c2ecf20Sopenharmony_ci struct hl_cs *cs; 1328c2ecf20Sopenharmony_ci bool first = true; 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci spin_lock(&dev_entry->cs_spinlock); 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci list_for_each_entry(cs, &dev_entry->cs_list, debugfs_list) { 1378c2ecf20Sopenharmony_ci if (first) { 1388c2ecf20Sopenharmony_ci first = false; 1398c2ecf20Sopenharmony_ci seq_puts(s, "\n"); 1408c2ecf20Sopenharmony_ci seq_puts(s, " CS ID CTX ASID CS RefCnt Submitted Completed\n"); 1418c2ecf20Sopenharmony_ci seq_puts(s, "------------------------------------------------------\n"); 1428c2ecf20Sopenharmony_ci } 1438c2ecf20Sopenharmony_ci seq_printf(s, 1448c2ecf20Sopenharmony_ci " %llu %d %d %d %d\n", 1458c2ecf20Sopenharmony_ci cs->sequence, cs->ctx->asid, 1468c2ecf20Sopenharmony_ci kref_read(&cs->refcount), 1478c2ecf20Sopenharmony_ci cs->submitted, cs->completed); 1488c2ecf20Sopenharmony_ci } 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ci spin_unlock(&dev_entry->cs_spinlock); 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci if (!first) 1538c2ecf20Sopenharmony_ci seq_puts(s, "\n"); 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci return 0; 1568c2ecf20Sopenharmony_ci} 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_cistatic int command_submission_jobs_show(struct seq_file *s, void *data) 1598c2ecf20Sopenharmony_ci{ 1608c2ecf20Sopenharmony_ci struct hl_debugfs_entry *entry = s->private; 1618c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *dev_entry = entry->dev_entry; 1628c2ecf20Sopenharmony_ci struct hl_cs_job *job; 1638c2ecf20Sopenharmony_ci bool first = true; 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci spin_lock(&dev_entry->cs_job_spinlock); 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci list_for_each_entry(job, &dev_entry->cs_job_list, debugfs_list) { 1688c2ecf20Sopenharmony_ci if (first) { 1698c2ecf20Sopenharmony_ci first = false; 1708c2ecf20Sopenharmony_ci seq_puts(s, "\n"); 1718c2ecf20Sopenharmony_ci seq_puts(s, " JOB ID CS ID CTX ASID H/W Queue\n"); 1728c2ecf20Sopenharmony_ci seq_puts(s, "---------------------------------------\n"); 1738c2ecf20Sopenharmony_ci } 1748c2ecf20Sopenharmony_ci if (job->cs) 1758c2ecf20Sopenharmony_ci seq_printf(s, 1768c2ecf20Sopenharmony_ci " %02d %llu %d %d\n", 1778c2ecf20Sopenharmony_ci job->id, job->cs->sequence, job->cs->ctx->asid, 1788c2ecf20Sopenharmony_ci job->hw_queue_id); 1798c2ecf20Sopenharmony_ci else 1808c2ecf20Sopenharmony_ci seq_printf(s, 1818c2ecf20Sopenharmony_ci " %02d 0 %d %d\n", 1828c2ecf20Sopenharmony_ci job->id, HL_KERNEL_ASID_ID, job->hw_queue_id); 1838c2ecf20Sopenharmony_ci } 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci spin_unlock(&dev_entry->cs_job_spinlock); 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci if (!first) 1888c2ecf20Sopenharmony_ci seq_puts(s, "\n"); 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci return 0; 1918c2ecf20Sopenharmony_ci} 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_cistatic int userptr_show(struct seq_file *s, void *data) 1948c2ecf20Sopenharmony_ci{ 1958c2ecf20Sopenharmony_ci struct hl_debugfs_entry *entry = s->private; 1968c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *dev_entry = entry->dev_entry; 1978c2ecf20Sopenharmony_ci struct hl_userptr *userptr; 1988c2ecf20Sopenharmony_ci char dma_dir[4][30] = {"DMA_BIDIRECTIONAL", "DMA_TO_DEVICE", 1998c2ecf20Sopenharmony_ci "DMA_FROM_DEVICE", "DMA_NONE"}; 2008c2ecf20Sopenharmony_ci bool first = true; 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_ci spin_lock(&dev_entry->userptr_spinlock); 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci list_for_each_entry(userptr, &dev_entry->userptr_list, debugfs_list) { 2058c2ecf20Sopenharmony_ci if (first) { 2068c2ecf20Sopenharmony_ci first = false; 2078c2ecf20Sopenharmony_ci seq_puts(s, "\n"); 2088c2ecf20Sopenharmony_ci seq_puts(s, " user virtual address size dma dir\n"); 2098c2ecf20Sopenharmony_ci seq_puts(s, "----------------------------------------------------------\n"); 2108c2ecf20Sopenharmony_ci } 2118c2ecf20Sopenharmony_ci seq_printf(s, 2128c2ecf20Sopenharmony_ci " 0x%-14llx %-10u %-30s\n", 2138c2ecf20Sopenharmony_ci userptr->addr, userptr->size, dma_dir[userptr->dir]); 2148c2ecf20Sopenharmony_ci } 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci spin_unlock(&dev_entry->userptr_spinlock); 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ci if (!first) 2198c2ecf20Sopenharmony_ci seq_puts(s, "\n"); 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci return 0; 2228c2ecf20Sopenharmony_ci} 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_cistatic int vm_show(struct seq_file *s, void *data) 2258c2ecf20Sopenharmony_ci{ 2268c2ecf20Sopenharmony_ci struct hl_debugfs_entry *entry = s->private; 2278c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *dev_entry = entry->dev_entry; 2288c2ecf20Sopenharmony_ci struct hl_ctx *ctx; 2298c2ecf20Sopenharmony_ci struct hl_vm *vm; 2308c2ecf20Sopenharmony_ci struct hl_vm_hash_node *hnode; 2318c2ecf20Sopenharmony_ci struct hl_userptr *userptr; 2328c2ecf20Sopenharmony_ci struct hl_vm_phys_pg_pack *phys_pg_pack = NULL; 2338c2ecf20Sopenharmony_ci enum vm_type_t *vm_type; 2348c2ecf20Sopenharmony_ci bool once = true; 2358c2ecf20Sopenharmony_ci u64 j; 2368c2ecf20Sopenharmony_ci int i; 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci if (!dev_entry->hdev->mmu_enable) 2398c2ecf20Sopenharmony_ci return 0; 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci spin_lock(&dev_entry->ctx_mem_hash_spinlock); 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci list_for_each_entry(ctx, &dev_entry->ctx_mem_hash_list, debugfs_list) { 2448c2ecf20Sopenharmony_ci once = false; 2458c2ecf20Sopenharmony_ci seq_puts(s, "\n\n----------------------------------------------------"); 2468c2ecf20Sopenharmony_ci seq_puts(s, "\n----------------------------------------------------\n\n"); 2478c2ecf20Sopenharmony_ci seq_printf(s, "ctx asid: %u\n", ctx->asid); 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_ci seq_puts(s, "\nmappings:\n\n"); 2508c2ecf20Sopenharmony_ci seq_puts(s, " virtual address size handle\n"); 2518c2ecf20Sopenharmony_ci seq_puts(s, "----------------------------------------------------\n"); 2528c2ecf20Sopenharmony_ci mutex_lock(&ctx->mem_hash_lock); 2538c2ecf20Sopenharmony_ci hash_for_each(ctx->mem_hash, i, hnode, node) { 2548c2ecf20Sopenharmony_ci vm_type = hnode->ptr; 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci if (*vm_type == VM_TYPE_USERPTR) { 2578c2ecf20Sopenharmony_ci userptr = hnode->ptr; 2588c2ecf20Sopenharmony_ci seq_printf(s, 2598c2ecf20Sopenharmony_ci " 0x%-14llx %-10u\n", 2608c2ecf20Sopenharmony_ci hnode->vaddr, userptr->size); 2618c2ecf20Sopenharmony_ci } else { 2628c2ecf20Sopenharmony_ci phys_pg_pack = hnode->ptr; 2638c2ecf20Sopenharmony_ci seq_printf(s, 2648c2ecf20Sopenharmony_ci " 0x%-14llx %-10llu %-4u\n", 2658c2ecf20Sopenharmony_ci hnode->vaddr, phys_pg_pack->total_size, 2668c2ecf20Sopenharmony_ci phys_pg_pack->handle); 2678c2ecf20Sopenharmony_ci } 2688c2ecf20Sopenharmony_ci } 2698c2ecf20Sopenharmony_ci mutex_unlock(&ctx->mem_hash_lock); 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci vm = &ctx->hdev->vm; 2728c2ecf20Sopenharmony_ci spin_lock(&vm->idr_lock); 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci if (!idr_is_empty(&vm->phys_pg_pack_handles)) 2758c2ecf20Sopenharmony_ci seq_puts(s, "\n\nallocations:\n"); 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_ci idr_for_each_entry(&vm->phys_pg_pack_handles, phys_pg_pack, i) { 2788c2ecf20Sopenharmony_ci if (phys_pg_pack->asid != ctx->asid) 2798c2ecf20Sopenharmony_ci continue; 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_ci seq_printf(s, "\nhandle: %u\n", phys_pg_pack->handle); 2828c2ecf20Sopenharmony_ci seq_printf(s, "page size: %u\n\n", 2838c2ecf20Sopenharmony_ci phys_pg_pack->page_size); 2848c2ecf20Sopenharmony_ci seq_puts(s, " physical address\n"); 2858c2ecf20Sopenharmony_ci seq_puts(s, "---------------------\n"); 2868c2ecf20Sopenharmony_ci for (j = 0 ; j < phys_pg_pack->npages ; j++) { 2878c2ecf20Sopenharmony_ci seq_printf(s, " 0x%-14llx\n", 2888c2ecf20Sopenharmony_ci phys_pg_pack->pages[j]); 2898c2ecf20Sopenharmony_ci } 2908c2ecf20Sopenharmony_ci } 2918c2ecf20Sopenharmony_ci spin_unlock(&vm->idr_lock); 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci } 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_ci spin_unlock(&dev_entry->ctx_mem_hash_spinlock); 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ci if (!once) 2988c2ecf20Sopenharmony_ci seq_puts(s, "\n"); 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_ci return 0; 3018c2ecf20Sopenharmony_ci} 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_ci/* these inline functions are copied from mmu.c */ 3048c2ecf20Sopenharmony_cistatic inline u64 get_hop0_addr(struct hl_ctx *ctx) 3058c2ecf20Sopenharmony_ci{ 3068c2ecf20Sopenharmony_ci return ctx->hdev->asic_prop.mmu_pgt_addr + 3078c2ecf20Sopenharmony_ci (ctx->asid * ctx->hdev->asic_prop.mmu_hop_table_size); 3088c2ecf20Sopenharmony_ci} 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_cistatic inline u64 get_hopN_pte_addr(struct hl_ctx *ctx, u64 hop_addr, 3118c2ecf20Sopenharmony_ci u64 virt_addr, u64 mask, u64 shift) 3128c2ecf20Sopenharmony_ci{ 3138c2ecf20Sopenharmony_ci return hop_addr + ctx->hdev->asic_prop.mmu_pte_size * 3148c2ecf20Sopenharmony_ci ((virt_addr & mask) >> shift); 3158c2ecf20Sopenharmony_ci} 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_cistatic inline u64 get_hop0_pte_addr(struct hl_ctx *ctx, 3188c2ecf20Sopenharmony_ci struct hl_mmu_properties *mmu_specs, 3198c2ecf20Sopenharmony_ci u64 hop_addr, u64 vaddr) 3208c2ecf20Sopenharmony_ci{ 3218c2ecf20Sopenharmony_ci return get_hopN_pte_addr(ctx, hop_addr, vaddr, mmu_specs->hop0_mask, 3228c2ecf20Sopenharmony_ci mmu_specs->hop0_shift); 3238c2ecf20Sopenharmony_ci} 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_cistatic inline u64 get_hop1_pte_addr(struct hl_ctx *ctx, 3268c2ecf20Sopenharmony_ci struct hl_mmu_properties *mmu_specs, 3278c2ecf20Sopenharmony_ci u64 hop_addr, u64 vaddr) 3288c2ecf20Sopenharmony_ci{ 3298c2ecf20Sopenharmony_ci return get_hopN_pte_addr(ctx, hop_addr, vaddr, mmu_specs->hop1_mask, 3308c2ecf20Sopenharmony_ci mmu_specs->hop1_shift); 3318c2ecf20Sopenharmony_ci} 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_cistatic inline u64 get_hop2_pte_addr(struct hl_ctx *ctx, 3348c2ecf20Sopenharmony_ci struct hl_mmu_properties *mmu_specs, 3358c2ecf20Sopenharmony_ci u64 hop_addr, u64 vaddr) 3368c2ecf20Sopenharmony_ci{ 3378c2ecf20Sopenharmony_ci return get_hopN_pte_addr(ctx, hop_addr, vaddr, mmu_specs->hop2_mask, 3388c2ecf20Sopenharmony_ci mmu_specs->hop2_shift); 3398c2ecf20Sopenharmony_ci} 3408c2ecf20Sopenharmony_ci 3418c2ecf20Sopenharmony_cistatic inline u64 get_hop3_pte_addr(struct hl_ctx *ctx, 3428c2ecf20Sopenharmony_ci struct hl_mmu_properties *mmu_specs, 3438c2ecf20Sopenharmony_ci u64 hop_addr, u64 vaddr) 3448c2ecf20Sopenharmony_ci{ 3458c2ecf20Sopenharmony_ci return get_hopN_pte_addr(ctx, hop_addr, vaddr, mmu_specs->hop3_mask, 3468c2ecf20Sopenharmony_ci mmu_specs->hop3_shift); 3478c2ecf20Sopenharmony_ci} 3488c2ecf20Sopenharmony_ci 3498c2ecf20Sopenharmony_cistatic inline u64 get_hop4_pte_addr(struct hl_ctx *ctx, 3508c2ecf20Sopenharmony_ci struct hl_mmu_properties *mmu_specs, 3518c2ecf20Sopenharmony_ci u64 hop_addr, u64 vaddr) 3528c2ecf20Sopenharmony_ci{ 3538c2ecf20Sopenharmony_ci return get_hopN_pte_addr(ctx, hop_addr, vaddr, mmu_specs->hop4_mask, 3548c2ecf20Sopenharmony_ci mmu_specs->hop4_shift); 3558c2ecf20Sopenharmony_ci} 3568c2ecf20Sopenharmony_ci 3578c2ecf20Sopenharmony_cistatic inline u64 get_hop5_pte_addr(struct hl_ctx *ctx, 3588c2ecf20Sopenharmony_ci struct hl_mmu_properties *mmu_specs, 3598c2ecf20Sopenharmony_ci u64 hop_addr, u64 vaddr) 3608c2ecf20Sopenharmony_ci{ 3618c2ecf20Sopenharmony_ci return get_hopN_pte_addr(ctx, hop_addr, vaddr, mmu_specs->hop5_mask, 3628c2ecf20Sopenharmony_ci mmu_specs->hop5_shift); 3638c2ecf20Sopenharmony_ci} 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_cistatic inline u64 get_next_hop_addr(u64 curr_pte) 3668c2ecf20Sopenharmony_ci{ 3678c2ecf20Sopenharmony_ci if (curr_pte & PAGE_PRESENT_MASK) 3688c2ecf20Sopenharmony_ci return curr_pte & HOP_PHYS_ADDR_MASK; 3698c2ecf20Sopenharmony_ci else 3708c2ecf20Sopenharmony_ci return ULLONG_MAX; 3718c2ecf20Sopenharmony_ci} 3728c2ecf20Sopenharmony_ci 3738c2ecf20Sopenharmony_cistatic int mmu_show(struct seq_file *s, void *data) 3748c2ecf20Sopenharmony_ci{ 3758c2ecf20Sopenharmony_ci struct hl_debugfs_entry *entry = s->private; 3768c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *dev_entry = entry->dev_entry; 3778c2ecf20Sopenharmony_ci struct hl_device *hdev = dev_entry->hdev; 3788c2ecf20Sopenharmony_ci struct asic_fixed_properties *prop = &hdev->asic_prop; 3798c2ecf20Sopenharmony_ci struct hl_mmu_properties *mmu_prop; 3808c2ecf20Sopenharmony_ci struct hl_ctx *ctx; 3818c2ecf20Sopenharmony_ci bool is_dram_addr; 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_ci u64 hop0_addr = 0, hop0_pte_addr = 0, hop0_pte = 0, 3848c2ecf20Sopenharmony_ci hop1_addr = 0, hop1_pte_addr = 0, hop1_pte = 0, 3858c2ecf20Sopenharmony_ci hop2_addr = 0, hop2_pte_addr = 0, hop2_pte = 0, 3868c2ecf20Sopenharmony_ci hop3_addr = 0, hop3_pte_addr = 0, hop3_pte = 0, 3878c2ecf20Sopenharmony_ci hop4_addr = 0, hop4_pte_addr = 0, hop4_pte = 0, 3888c2ecf20Sopenharmony_ci hop5_addr = 0, hop5_pte_addr = 0, hop5_pte = 0, 3898c2ecf20Sopenharmony_ci virt_addr = dev_entry->mmu_addr; 3908c2ecf20Sopenharmony_ci 3918c2ecf20Sopenharmony_ci if (!hdev->mmu_enable) 3928c2ecf20Sopenharmony_ci return 0; 3938c2ecf20Sopenharmony_ci 3948c2ecf20Sopenharmony_ci if (dev_entry->mmu_asid == HL_KERNEL_ASID_ID) 3958c2ecf20Sopenharmony_ci ctx = hdev->kernel_ctx; 3968c2ecf20Sopenharmony_ci else 3978c2ecf20Sopenharmony_ci ctx = hdev->compute_ctx; 3988c2ecf20Sopenharmony_ci 3998c2ecf20Sopenharmony_ci if (!ctx) { 4008c2ecf20Sopenharmony_ci dev_err(hdev->dev, "no ctx available\n"); 4018c2ecf20Sopenharmony_ci return 0; 4028c2ecf20Sopenharmony_ci } 4038c2ecf20Sopenharmony_ci 4048c2ecf20Sopenharmony_ci is_dram_addr = hl_mem_area_inside_range(virt_addr, prop->dmmu.page_size, 4058c2ecf20Sopenharmony_ci prop->dmmu.start_addr, 4068c2ecf20Sopenharmony_ci prop->dmmu.end_addr); 4078c2ecf20Sopenharmony_ci 4088c2ecf20Sopenharmony_ci /* shifts and masks are the same in PMMU and HPMMU, use one of them */ 4098c2ecf20Sopenharmony_ci mmu_prop = is_dram_addr ? &prop->dmmu : &prop->pmmu; 4108c2ecf20Sopenharmony_ci 4118c2ecf20Sopenharmony_ci mutex_lock(&ctx->mmu_lock); 4128c2ecf20Sopenharmony_ci 4138c2ecf20Sopenharmony_ci /* the following lookup is copied from unmap() in mmu.c */ 4148c2ecf20Sopenharmony_ci 4158c2ecf20Sopenharmony_ci hop0_addr = get_hop0_addr(ctx); 4168c2ecf20Sopenharmony_ci hop0_pte_addr = get_hop0_pte_addr(ctx, mmu_prop, hop0_addr, virt_addr); 4178c2ecf20Sopenharmony_ci hop0_pte = hdev->asic_funcs->read_pte(hdev, hop0_pte_addr); 4188c2ecf20Sopenharmony_ci hop1_addr = get_next_hop_addr(hop0_pte); 4198c2ecf20Sopenharmony_ci 4208c2ecf20Sopenharmony_ci if (hop1_addr == ULLONG_MAX) 4218c2ecf20Sopenharmony_ci goto not_mapped; 4228c2ecf20Sopenharmony_ci 4238c2ecf20Sopenharmony_ci hop1_pte_addr = get_hop1_pte_addr(ctx, mmu_prop, hop1_addr, virt_addr); 4248c2ecf20Sopenharmony_ci hop1_pte = hdev->asic_funcs->read_pte(hdev, hop1_pte_addr); 4258c2ecf20Sopenharmony_ci hop2_addr = get_next_hop_addr(hop1_pte); 4268c2ecf20Sopenharmony_ci 4278c2ecf20Sopenharmony_ci if (hop2_addr == ULLONG_MAX) 4288c2ecf20Sopenharmony_ci goto not_mapped; 4298c2ecf20Sopenharmony_ci 4308c2ecf20Sopenharmony_ci hop2_pte_addr = get_hop2_pte_addr(ctx, mmu_prop, hop2_addr, virt_addr); 4318c2ecf20Sopenharmony_ci hop2_pte = hdev->asic_funcs->read_pte(hdev, hop2_pte_addr); 4328c2ecf20Sopenharmony_ci hop3_addr = get_next_hop_addr(hop2_pte); 4338c2ecf20Sopenharmony_ci 4348c2ecf20Sopenharmony_ci if (hop3_addr == ULLONG_MAX) 4358c2ecf20Sopenharmony_ci goto not_mapped; 4368c2ecf20Sopenharmony_ci 4378c2ecf20Sopenharmony_ci hop3_pte_addr = get_hop3_pte_addr(ctx, mmu_prop, hop3_addr, virt_addr); 4388c2ecf20Sopenharmony_ci hop3_pte = hdev->asic_funcs->read_pte(hdev, hop3_pte_addr); 4398c2ecf20Sopenharmony_ci 4408c2ecf20Sopenharmony_ci if (mmu_prop->num_hops == MMU_ARCH_5_HOPS) { 4418c2ecf20Sopenharmony_ci if (!(hop3_pte & LAST_MASK)) { 4428c2ecf20Sopenharmony_ci hop4_addr = get_next_hop_addr(hop3_pte); 4438c2ecf20Sopenharmony_ci 4448c2ecf20Sopenharmony_ci if (hop4_addr == ULLONG_MAX) 4458c2ecf20Sopenharmony_ci goto not_mapped; 4468c2ecf20Sopenharmony_ci 4478c2ecf20Sopenharmony_ci hop4_pte_addr = get_hop4_pte_addr(ctx, mmu_prop, 4488c2ecf20Sopenharmony_ci hop4_addr, virt_addr); 4498c2ecf20Sopenharmony_ci hop4_pte = hdev->asic_funcs->read_pte(hdev, 4508c2ecf20Sopenharmony_ci hop4_pte_addr); 4518c2ecf20Sopenharmony_ci if (!(hop4_pte & PAGE_PRESENT_MASK)) 4528c2ecf20Sopenharmony_ci goto not_mapped; 4538c2ecf20Sopenharmony_ci } else { 4548c2ecf20Sopenharmony_ci if (!(hop3_pte & PAGE_PRESENT_MASK)) 4558c2ecf20Sopenharmony_ci goto not_mapped; 4568c2ecf20Sopenharmony_ci } 4578c2ecf20Sopenharmony_ci } else { 4588c2ecf20Sopenharmony_ci hop4_addr = get_next_hop_addr(hop3_pte); 4598c2ecf20Sopenharmony_ci 4608c2ecf20Sopenharmony_ci if (hop4_addr == ULLONG_MAX) 4618c2ecf20Sopenharmony_ci goto not_mapped; 4628c2ecf20Sopenharmony_ci 4638c2ecf20Sopenharmony_ci hop4_pte_addr = get_hop4_pte_addr(ctx, mmu_prop, 4648c2ecf20Sopenharmony_ci hop4_addr, virt_addr); 4658c2ecf20Sopenharmony_ci hop4_pte = hdev->asic_funcs->read_pte(hdev, 4668c2ecf20Sopenharmony_ci hop4_pte_addr); 4678c2ecf20Sopenharmony_ci if (!(hop4_pte & LAST_MASK)) { 4688c2ecf20Sopenharmony_ci hop5_addr = get_next_hop_addr(hop4_pte); 4698c2ecf20Sopenharmony_ci 4708c2ecf20Sopenharmony_ci if (hop5_addr == ULLONG_MAX) 4718c2ecf20Sopenharmony_ci goto not_mapped; 4728c2ecf20Sopenharmony_ci 4738c2ecf20Sopenharmony_ci hop5_pte_addr = get_hop5_pte_addr(ctx, mmu_prop, 4748c2ecf20Sopenharmony_ci hop5_addr, virt_addr); 4758c2ecf20Sopenharmony_ci hop5_pte = hdev->asic_funcs->read_pte(hdev, 4768c2ecf20Sopenharmony_ci hop5_pte_addr); 4778c2ecf20Sopenharmony_ci if (!(hop5_pte & PAGE_PRESENT_MASK)) 4788c2ecf20Sopenharmony_ci goto not_mapped; 4798c2ecf20Sopenharmony_ci } else { 4808c2ecf20Sopenharmony_ci if (!(hop4_pte & PAGE_PRESENT_MASK)) 4818c2ecf20Sopenharmony_ci goto not_mapped; 4828c2ecf20Sopenharmony_ci } 4838c2ecf20Sopenharmony_ci } 4848c2ecf20Sopenharmony_ci 4858c2ecf20Sopenharmony_ci seq_printf(s, "asid: %u, virt_addr: 0x%llx\n", 4868c2ecf20Sopenharmony_ci dev_entry->mmu_asid, dev_entry->mmu_addr); 4878c2ecf20Sopenharmony_ci 4888c2ecf20Sopenharmony_ci seq_printf(s, "hop0_addr: 0x%llx\n", hop0_addr); 4898c2ecf20Sopenharmony_ci seq_printf(s, "hop0_pte_addr: 0x%llx\n", hop0_pte_addr); 4908c2ecf20Sopenharmony_ci seq_printf(s, "hop0_pte: 0x%llx\n", hop0_pte); 4918c2ecf20Sopenharmony_ci 4928c2ecf20Sopenharmony_ci seq_printf(s, "hop1_addr: 0x%llx\n", hop1_addr); 4938c2ecf20Sopenharmony_ci seq_printf(s, "hop1_pte_addr: 0x%llx\n", hop1_pte_addr); 4948c2ecf20Sopenharmony_ci seq_printf(s, "hop1_pte: 0x%llx\n", hop1_pte); 4958c2ecf20Sopenharmony_ci 4968c2ecf20Sopenharmony_ci seq_printf(s, "hop2_addr: 0x%llx\n", hop2_addr); 4978c2ecf20Sopenharmony_ci seq_printf(s, "hop2_pte_addr: 0x%llx\n", hop2_pte_addr); 4988c2ecf20Sopenharmony_ci seq_printf(s, "hop2_pte: 0x%llx\n", hop2_pte); 4998c2ecf20Sopenharmony_ci 5008c2ecf20Sopenharmony_ci seq_printf(s, "hop3_addr: 0x%llx\n", hop3_addr); 5018c2ecf20Sopenharmony_ci seq_printf(s, "hop3_pte_addr: 0x%llx\n", hop3_pte_addr); 5028c2ecf20Sopenharmony_ci seq_printf(s, "hop3_pte: 0x%llx\n", hop3_pte); 5038c2ecf20Sopenharmony_ci 5048c2ecf20Sopenharmony_ci if (mmu_prop->num_hops == MMU_ARCH_5_HOPS) { 5058c2ecf20Sopenharmony_ci if (!(hop3_pte & LAST_MASK)) { 5068c2ecf20Sopenharmony_ci seq_printf(s, "hop4_addr: 0x%llx\n", hop4_addr); 5078c2ecf20Sopenharmony_ci seq_printf(s, "hop4_pte_addr: 0x%llx\n", hop4_pte_addr); 5088c2ecf20Sopenharmony_ci seq_printf(s, "hop4_pte: 0x%llx\n", hop4_pte); 5098c2ecf20Sopenharmony_ci } 5108c2ecf20Sopenharmony_ci } else { 5118c2ecf20Sopenharmony_ci seq_printf(s, "hop4_addr: 0x%llx\n", hop4_addr); 5128c2ecf20Sopenharmony_ci seq_printf(s, "hop4_pte_addr: 0x%llx\n", hop4_pte_addr); 5138c2ecf20Sopenharmony_ci seq_printf(s, "hop4_pte: 0x%llx\n", hop4_pte); 5148c2ecf20Sopenharmony_ci 5158c2ecf20Sopenharmony_ci if (!(hop4_pte & LAST_MASK)) { 5168c2ecf20Sopenharmony_ci seq_printf(s, "hop5_addr: 0x%llx\n", hop5_addr); 5178c2ecf20Sopenharmony_ci seq_printf(s, "hop5_pte_addr: 0x%llx\n", hop5_pte_addr); 5188c2ecf20Sopenharmony_ci seq_printf(s, "hop5_pte: 0x%llx\n", hop5_pte); 5198c2ecf20Sopenharmony_ci } 5208c2ecf20Sopenharmony_ci } 5218c2ecf20Sopenharmony_ci 5228c2ecf20Sopenharmony_ci goto out; 5238c2ecf20Sopenharmony_ci 5248c2ecf20Sopenharmony_cinot_mapped: 5258c2ecf20Sopenharmony_ci dev_err(hdev->dev, "virt addr 0x%llx is not mapped to phys addr\n", 5268c2ecf20Sopenharmony_ci virt_addr); 5278c2ecf20Sopenharmony_ciout: 5288c2ecf20Sopenharmony_ci mutex_unlock(&ctx->mmu_lock); 5298c2ecf20Sopenharmony_ci 5308c2ecf20Sopenharmony_ci return 0; 5318c2ecf20Sopenharmony_ci} 5328c2ecf20Sopenharmony_ci 5338c2ecf20Sopenharmony_cistatic ssize_t mmu_asid_va_write(struct file *file, const char __user *buf, 5348c2ecf20Sopenharmony_ci size_t count, loff_t *f_pos) 5358c2ecf20Sopenharmony_ci{ 5368c2ecf20Sopenharmony_ci struct seq_file *s = file->private_data; 5378c2ecf20Sopenharmony_ci struct hl_debugfs_entry *entry = s->private; 5388c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *dev_entry = entry->dev_entry; 5398c2ecf20Sopenharmony_ci struct hl_device *hdev = dev_entry->hdev; 5408c2ecf20Sopenharmony_ci char kbuf[MMU_KBUF_SIZE]; 5418c2ecf20Sopenharmony_ci char *c; 5428c2ecf20Sopenharmony_ci ssize_t rc; 5438c2ecf20Sopenharmony_ci 5448c2ecf20Sopenharmony_ci if (!hdev->mmu_enable) 5458c2ecf20Sopenharmony_ci return count; 5468c2ecf20Sopenharmony_ci 5478c2ecf20Sopenharmony_ci if (count > sizeof(kbuf) - 1) 5488c2ecf20Sopenharmony_ci goto err; 5498c2ecf20Sopenharmony_ci if (copy_from_user(kbuf, buf, count)) 5508c2ecf20Sopenharmony_ci goto err; 5518c2ecf20Sopenharmony_ci kbuf[count] = 0; 5528c2ecf20Sopenharmony_ci 5538c2ecf20Sopenharmony_ci c = strchr(kbuf, ' '); 5548c2ecf20Sopenharmony_ci if (!c) 5558c2ecf20Sopenharmony_ci goto err; 5568c2ecf20Sopenharmony_ci *c = '\0'; 5578c2ecf20Sopenharmony_ci 5588c2ecf20Sopenharmony_ci rc = kstrtouint(kbuf, 10, &dev_entry->mmu_asid); 5598c2ecf20Sopenharmony_ci if (rc) 5608c2ecf20Sopenharmony_ci goto err; 5618c2ecf20Sopenharmony_ci 5628c2ecf20Sopenharmony_ci if (strncmp(c+1, "0x", 2)) 5638c2ecf20Sopenharmony_ci goto err; 5648c2ecf20Sopenharmony_ci rc = kstrtoull(c+3, 16, &dev_entry->mmu_addr); 5658c2ecf20Sopenharmony_ci if (rc) 5668c2ecf20Sopenharmony_ci goto err; 5678c2ecf20Sopenharmony_ci 5688c2ecf20Sopenharmony_ci return count; 5698c2ecf20Sopenharmony_ci 5708c2ecf20Sopenharmony_cierr: 5718c2ecf20Sopenharmony_ci dev_err(hdev->dev, "usage: echo <asid> <0xaddr> > mmu\n"); 5728c2ecf20Sopenharmony_ci 5738c2ecf20Sopenharmony_ci return -EINVAL; 5748c2ecf20Sopenharmony_ci} 5758c2ecf20Sopenharmony_ci 5768c2ecf20Sopenharmony_cistatic int engines_show(struct seq_file *s, void *data) 5778c2ecf20Sopenharmony_ci{ 5788c2ecf20Sopenharmony_ci struct hl_debugfs_entry *entry = s->private; 5798c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *dev_entry = entry->dev_entry; 5808c2ecf20Sopenharmony_ci struct hl_device *hdev = dev_entry->hdev; 5818c2ecf20Sopenharmony_ci 5828c2ecf20Sopenharmony_ci if (atomic_read(&hdev->in_reset)) { 5838c2ecf20Sopenharmony_ci dev_warn_ratelimited(hdev->dev, 5848c2ecf20Sopenharmony_ci "Can't check device idle during reset\n"); 5858c2ecf20Sopenharmony_ci return 0; 5868c2ecf20Sopenharmony_ci } 5878c2ecf20Sopenharmony_ci 5888c2ecf20Sopenharmony_ci hdev->asic_funcs->is_device_idle(hdev, NULL, s); 5898c2ecf20Sopenharmony_ci 5908c2ecf20Sopenharmony_ci return 0; 5918c2ecf20Sopenharmony_ci} 5928c2ecf20Sopenharmony_ci 5938c2ecf20Sopenharmony_cistatic bool hl_is_device_va(struct hl_device *hdev, u64 addr) 5948c2ecf20Sopenharmony_ci{ 5958c2ecf20Sopenharmony_ci struct asic_fixed_properties *prop = &hdev->asic_prop; 5968c2ecf20Sopenharmony_ci 5978c2ecf20Sopenharmony_ci if (!hdev->mmu_enable) 5988c2ecf20Sopenharmony_ci goto out; 5998c2ecf20Sopenharmony_ci 6008c2ecf20Sopenharmony_ci if (hdev->dram_supports_virtual_memory && 6018c2ecf20Sopenharmony_ci (addr >= prop->dmmu.start_addr && addr < prop->dmmu.end_addr)) 6028c2ecf20Sopenharmony_ci return true; 6038c2ecf20Sopenharmony_ci 6048c2ecf20Sopenharmony_ci if (addr >= prop->pmmu.start_addr && 6058c2ecf20Sopenharmony_ci addr < prop->pmmu.end_addr) 6068c2ecf20Sopenharmony_ci return true; 6078c2ecf20Sopenharmony_ci 6088c2ecf20Sopenharmony_ci if (addr >= prop->pmmu_huge.start_addr && 6098c2ecf20Sopenharmony_ci addr < prop->pmmu_huge.end_addr) 6108c2ecf20Sopenharmony_ci return true; 6118c2ecf20Sopenharmony_ciout: 6128c2ecf20Sopenharmony_ci return false; 6138c2ecf20Sopenharmony_ci} 6148c2ecf20Sopenharmony_ci 6158c2ecf20Sopenharmony_cistatic int device_va_to_pa(struct hl_device *hdev, u64 virt_addr, 6168c2ecf20Sopenharmony_ci u64 *phys_addr) 6178c2ecf20Sopenharmony_ci{ 6188c2ecf20Sopenharmony_ci struct hl_ctx *ctx = hdev->compute_ctx; 6198c2ecf20Sopenharmony_ci struct asic_fixed_properties *prop = &hdev->asic_prop; 6208c2ecf20Sopenharmony_ci struct hl_mmu_properties *mmu_prop; 6218c2ecf20Sopenharmony_ci u64 hop_addr, hop_pte_addr, hop_pte; 6228c2ecf20Sopenharmony_ci u64 offset_mask = HOP4_MASK | FLAGS_MASK; 6238c2ecf20Sopenharmony_ci int rc = 0; 6248c2ecf20Sopenharmony_ci bool is_dram_addr; 6258c2ecf20Sopenharmony_ci 6268c2ecf20Sopenharmony_ci if (!ctx) { 6278c2ecf20Sopenharmony_ci dev_err(hdev->dev, "no ctx available\n"); 6288c2ecf20Sopenharmony_ci return -EINVAL; 6298c2ecf20Sopenharmony_ci } 6308c2ecf20Sopenharmony_ci 6318c2ecf20Sopenharmony_ci is_dram_addr = hl_mem_area_inside_range(virt_addr, prop->dmmu.page_size, 6328c2ecf20Sopenharmony_ci prop->dmmu.start_addr, 6338c2ecf20Sopenharmony_ci prop->dmmu.end_addr); 6348c2ecf20Sopenharmony_ci 6358c2ecf20Sopenharmony_ci /* shifts and masks are the same in PMMU and HPMMU, use one of them */ 6368c2ecf20Sopenharmony_ci mmu_prop = is_dram_addr ? &prop->dmmu : &prop->pmmu; 6378c2ecf20Sopenharmony_ci 6388c2ecf20Sopenharmony_ci mutex_lock(&ctx->mmu_lock); 6398c2ecf20Sopenharmony_ci 6408c2ecf20Sopenharmony_ci /* hop 0 */ 6418c2ecf20Sopenharmony_ci hop_addr = get_hop0_addr(ctx); 6428c2ecf20Sopenharmony_ci hop_pte_addr = get_hop0_pte_addr(ctx, mmu_prop, hop_addr, virt_addr); 6438c2ecf20Sopenharmony_ci hop_pte = hdev->asic_funcs->read_pte(hdev, hop_pte_addr); 6448c2ecf20Sopenharmony_ci 6458c2ecf20Sopenharmony_ci /* hop 1 */ 6468c2ecf20Sopenharmony_ci hop_addr = get_next_hop_addr(hop_pte); 6478c2ecf20Sopenharmony_ci if (hop_addr == ULLONG_MAX) 6488c2ecf20Sopenharmony_ci goto not_mapped; 6498c2ecf20Sopenharmony_ci hop_pte_addr = get_hop1_pte_addr(ctx, mmu_prop, hop_addr, virt_addr); 6508c2ecf20Sopenharmony_ci hop_pte = hdev->asic_funcs->read_pte(hdev, hop_pte_addr); 6518c2ecf20Sopenharmony_ci 6528c2ecf20Sopenharmony_ci /* hop 2 */ 6538c2ecf20Sopenharmony_ci hop_addr = get_next_hop_addr(hop_pte); 6548c2ecf20Sopenharmony_ci if (hop_addr == ULLONG_MAX) 6558c2ecf20Sopenharmony_ci goto not_mapped; 6568c2ecf20Sopenharmony_ci hop_pte_addr = get_hop2_pte_addr(ctx, mmu_prop, hop_addr, virt_addr); 6578c2ecf20Sopenharmony_ci hop_pte = hdev->asic_funcs->read_pte(hdev, hop_pte_addr); 6588c2ecf20Sopenharmony_ci 6598c2ecf20Sopenharmony_ci /* hop 3 */ 6608c2ecf20Sopenharmony_ci hop_addr = get_next_hop_addr(hop_pte); 6618c2ecf20Sopenharmony_ci if (hop_addr == ULLONG_MAX) 6628c2ecf20Sopenharmony_ci goto not_mapped; 6638c2ecf20Sopenharmony_ci hop_pte_addr = get_hop3_pte_addr(ctx, mmu_prop, hop_addr, virt_addr); 6648c2ecf20Sopenharmony_ci hop_pte = hdev->asic_funcs->read_pte(hdev, hop_pte_addr); 6658c2ecf20Sopenharmony_ci 6668c2ecf20Sopenharmony_ci if (!(hop_pte & LAST_MASK)) { 6678c2ecf20Sopenharmony_ci /* hop 4 */ 6688c2ecf20Sopenharmony_ci hop_addr = get_next_hop_addr(hop_pte); 6698c2ecf20Sopenharmony_ci if (hop_addr == ULLONG_MAX) 6708c2ecf20Sopenharmony_ci goto not_mapped; 6718c2ecf20Sopenharmony_ci hop_pte_addr = get_hop4_pte_addr(ctx, mmu_prop, hop_addr, 6728c2ecf20Sopenharmony_ci virt_addr); 6738c2ecf20Sopenharmony_ci hop_pte = hdev->asic_funcs->read_pte(hdev, hop_pte_addr); 6748c2ecf20Sopenharmony_ci 6758c2ecf20Sopenharmony_ci offset_mask = FLAGS_MASK; 6768c2ecf20Sopenharmony_ci } 6778c2ecf20Sopenharmony_ci 6788c2ecf20Sopenharmony_ci if (!(hop_pte & PAGE_PRESENT_MASK)) 6798c2ecf20Sopenharmony_ci goto not_mapped; 6808c2ecf20Sopenharmony_ci 6818c2ecf20Sopenharmony_ci *phys_addr = (hop_pte & ~offset_mask) | (virt_addr & offset_mask); 6828c2ecf20Sopenharmony_ci 6838c2ecf20Sopenharmony_ci goto out; 6848c2ecf20Sopenharmony_ci 6858c2ecf20Sopenharmony_cinot_mapped: 6868c2ecf20Sopenharmony_ci dev_err(hdev->dev, "virt addr 0x%llx is not mapped to phys addr\n", 6878c2ecf20Sopenharmony_ci virt_addr); 6888c2ecf20Sopenharmony_ci rc = -EINVAL; 6898c2ecf20Sopenharmony_ciout: 6908c2ecf20Sopenharmony_ci mutex_unlock(&ctx->mmu_lock); 6918c2ecf20Sopenharmony_ci return rc; 6928c2ecf20Sopenharmony_ci} 6938c2ecf20Sopenharmony_ci 6948c2ecf20Sopenharmony_cistatic ssize_t hl_data_read32(struct file *f, char __user *buf, 6958c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 6968c2ecf20Sopenharmony_ci{ 6978c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *entry = file_inode(f)->i_private; 6988c2ecf20Sopenharmony_ci struct hl_device *hdev = entry->hdev; 6998c2ecf20Sopenharmony_ci char tmp_buf[32]; 7008c2ecf20Sopenharmony_ci u64 addr = entry->addr; 7018c2ecf20Sopenharmony_ci u32 val; 7028c2ecf20Sopenharmony_ci ssize_t rc; 7038c2ecf20Sopenharmony_ci 7048c2ecf20Sopenharmony_ci if (atomic_read(&hdev->in_reset)) { 7058c2ecf20Sopenharmony_ci dev_warn_ratelimited(hdev->dev, "Can't read during reset\n"); 7068c2ecf20Sopenharmony_ci return 0; 7078c2ecf20Sopenharmony_ci } 7088c2ecf20Sopenharmony_ci 7098c2ecf20Sopenharmony_ci if (*ppos) 7108c2ecf20Sopenharmony_ci return 0; 7118c2ecf20Sopenharmony_ci 7128c2ecf20Sopenharmony_ci if (hl_is_device_va(hdev, addr)) { 7138c2ecf20Sopenharmony_ci rc = device_va_to_pa(hdev, addr, &addr); 7148c2ecf20Sopenharmony_ci if (rc) 7158c2ecf20Sopenharmony_ci return rc; 7168c2ecf20Sopenharmony_ci } 7178c2ecf20Sopenharmony_ci 7188c2ecf20Sopenharmony_ci rc = hdev->asic_funcs->debugfs_read32(hdev, addr, &val); 7198c2ecf20Sopenharmony_ci if (rc) { 7208c2ecf20Sopenharmony_ci dev_err(hdev->dev, "Failed to read from 0x%010llx\n", addr); 7218c2ecf20Sopenharmony_ci return rc; 7228c2ecf20Sopenharmony_ci } 7238c2ecf20Sopenharmony_ci 7248c2ecf20Sopenharmony_ci sprintf(tmp_buf, "0x%08x\n", val); 7258c2ecf20Sopenharmony_ci return simple_read_from_buffer(buf, count, ppos, tmp_buf, 7268c2ecf20Sopenharmony_ci strlen(tmp_buf)); 7278c2ecf20Sopenharmony_ci} 7288c2ecf20Sopenharmony_ci 7298c2ecf20Sopenharmony_cistatic ssize_t hl_data_write32(struct file *f, const char __user *buf, 7308c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 7318c2ecf20Sopenharmony_ci{ 7328c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *entry = file_inode(f)->i_private; 7338c2ecf20Sopenharmony_ci struct hl_device *hdev = entry->hdev; 7348c2ecf20Sopenharmony_ci u64 addr = entry->addr; 7358c2ecf20Sopenharmony_ci u32 value; 7368c2ecf20Sopenharmony_ci ssize_t rc; 7378c2ecf20Sopenharmony_ci 7388c2ecf20Sopenharmony_ci if (atomic_read(&hdev->in_reset)) { 7398c2ecf20Sopenharmony_ci dev_warn_ratelimited(hdev->dev, "Can't write during reset\n"); 7408c2ecf20Sopenharmony_ci return 0; 7418c2ecf20Sopenharmony_ci } 7428c2ecf20Sopenharmony_ci 7438c2ecf20Sopenharmony_ci rc = kstrtouint_from_user(buf, count, 16, &value); 7448c2ecf20Sopenharmony_ci if (rc) 7458c2ecf20Sopenharmony_ci return rc; 7468c2ecf20Sopenharmony_ci 7478c2ecf20Sopenharmony_ci if (hl_is_device_va(hdev, addr)) { 7488c2ecf20Sopenharmony_ci rc = device_va_to_pa(hdev, addr, &addr); 7498c2ecf20Sopenharmony_ci if (rc) 7508c2ecf20Sopenharmony_ci return rc; 7518c2ecf20Sopenharmony_ci } 7528c2ecf20Sopenharmony_ci 7538c2ecf20Sopenharmony_ci rc = hdev->asic_funcs->debugfs_write32(hdev, addr, value); 7548c2ecf20Sopenharmony_ci if (rc) { 7558c2ecf20Sopenharmony_ci dev_err(hdev->dev, "Failed to write 0x%08x to 0x%010llx\n", 7568c2ecf20Sopenharmony_ci value, addr); 7578c2ecf20Sopenharmony_ci return rc; 7588c2ecf20Sopenharmony_ci } 7598c2ecf20Sopenharmony_ci 7608c2ecf20Sopenharmony_ci return count; 7618c2ecf20Sopenharmony_ci} 7628c2ecf20Sopenharmony_ci 7638c2ecf20Sopenharmony_cistatic ssize_t hl_data_read64(struct file *f, char __user *buf, 7648c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 7658c2ecf20Sopenharmony_ci{ 7668c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *entry = file_inode(f)->i_private; 7678c2ecf20Sopenharmony_ci struct hl_device *hdev = entry->hdev; 7688c2ecf20Sopenharmony_ci char tmp_buf[32]; 7698c2ecf20Sopenharmony_ci u64 addr = entry->addr; 7708c2ecf20Sopenharmony_ci u64 val; 7718c2ecf20Sopenharmony_ci ssize_t rc; 7728c2ecf20Sopenharmony_ci 7738c2ecf20Sopenharmony_ci if (*ppos) 7748c2ecf20Sopenharmony_ci return 0; 7758c2ecf20Sopenharmony_ci 7768c2ecf20Sopenharmony_ci if (hl_is_device_va(hdev, addr)) { 7778c2ecf20Sopenharmony_ci rc = device_va_to_pa(hdev, addr, &addr); 7788c2ecf20Sopenharmony_ci if (rc) 7798c2ecf20Sopenharmony_ci return rc; 7808c2ecf20Sopenharmony_ci } 7818c2ecf20Sopenharmony_ci 7828c2ecf20Sopenharmony_ci rc = hdev->asic_funcs->debugfs_read64(hdev, addr, &val); 7838c2ecf20Sopenharmony_ci if (rc) { 7848c2ecf20Sopenharmony_ci dev_err(hdev->dev, "Failed to read from 0x%010llx\n", addr); 7858c2ecf20Sopenharmony_ci return rc; 7868c2ecf20Sopenharmony_ci } 7878c2ecf20Sopenharmony_ci 7888c2ecf20Sopenharmony_ci sprintf(tmp_buf, "0x%016llx\n", val); 7898c2ecf20Sopenharmony_ci return simple_read_from_buffer(buf, count, ppos, tmp_buf, 7908c2ecf20Sopenharmony_ci strlen(tmp_buf)); 7918c2ecf20Sopenharmony_ci} 7928c2ecf20Sopenharmony_ci 7938c2ecf20Sopenharmony_cistatic ssize_t hl_data_write64(struct file *f, const char __user *buf, 7948c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 7958c2ecf20Sopenharmony_ci{ 7968c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *entry = file_inode(f)->i_private; 7978c2ecf20Sopenharmony_ci struct hl_device *hdev = entry->hdev; 7988c2ecf20Sopenharmony_ci u64 addr = entry->addr; 7998c2ecf20Sopenharmony_ci u64 value; 8008c2ecf20Sopenharmony_ci ssize_t rc; 8018c2ecf20Sopenharmony_ci 8028c2ecf20Sopenharmony_ci rc = kstrtoull_from_user(buf, count, 16, &value); 8038c2ecf20Sopenharmony_ci if (rc) 8048c2ecf20Sopenharmony_ci return rc; 8058c2ecf20Sopenharmony_ci 8068c2ecf20Sopenharmony_ci if (hl_is_device_va(hdev, addr)) { 8078c2ecf20Sopenharmony_ci rc = device_va_to_pa(hdev, addr, &addr); 8088c2ecf20Sopenharmony_ci if (rc) 8098c2ecf20Sopenharmony_ci return rc; 8108c2ecf20Sopenharmony_ci } 8118c2ecf20Sopenharmony_ci 8128c2ecf20Sopenharmony_ci rc = hdev->asic_funcs->debugfs_write64(hdev, addr, value); 8138c2ecf20Sopenharmony_ci if (rc) { 8148c2ecf20Sopenharmony_ci dev_err(hdev->dev, "Failed to write 0x%016llx to 0x%010llx\n", 8158c2ecf20Sopenharmony_ci value, addr); 8168c2ecf20Sopenharmony_ci return rc; 8178c2ecf20Sopenharmony_ci } 8188c2ecf20Sopenharmony_ci 8198c2ecf20Sopenharmony_ci return count; 8208c2ecf20Sopenharmony_ci} 8218c2ecf20Sopenharmony_ci 8228c2ecf20Sopenharmony_cistatic ssize_t hl_get_power_state(struct file *f, char __user *buf, 8238c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 8248c2ecf20Sopenharmony_ci{ 8258c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *entry = file_inode(f)->i_private; 8268c2ecf20Sopenharmony_ci struct hl_device *hdev = entry->hdev; 8278c2ecf20Sopenharmony_ci char tmp_buf[200]; 8288c2ecf20Sopenharmony_ci int i; 8298c2ecf20Sopenharmony_ci 8308c2ecf20Sopenharmony_ci if (*ppos) 8318c2ecf20Sopenharmony_ci return 0; 8328c2ecf20Sopenharmony_ci 8338c2ecf20Sopenharmony_ci if (hdev->pdev->current_state == PCI_D0) 8348c2ecf20Sopenharmony_ci i = 1; 8358c2ecf20Sopenharmony_ci else if (hdev->pdev->current_state == PCI_D3hot) 8368c2ecf20Sopenharmony_ci i = 2; 8378c2ecf20Sopenharmony_ci else 8388c2ecf20Sopenharmony_ci i = 3; 8398c2ecf20Sopenharmony_ci 8408c2ecf20Sopenharmony_ci sprintf(tmp_buf, 8418c2ecf20Sopenharmony_ci "current power state: %d\n1 - D0\n2 - D3hot\n3 - Unknown\n", i); 8428c2ecf20Sopenharmony_ci return simple_read_from_buffer(buf, count, ppos, tmp_buf, 8438c2ecf20Sopenharmony_ci strlen(tmp_buf)); 8448c2ecf20Sopenharmony_ci} 8458c2ecf20Sopenharmony_ci 8468c2ecf20Sopenharmony_cistatic ssize_t hl_set_power_state(struct file *f, const char __user *buf, 8478c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 8488c2ecf20Sopenharmony_ci{ 8498c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *entry = file_inode(f)->i_private; 8508c2ecf20Sopenharmony_ci struct hl_device *hdev = entry->hdev; 8518c2ecf20Sopenharmony_ci u32 value; 8528c2ecf20Sopenharmony_ci ssize_t rc; 8538c2ecf20Sopenharmony_ci 8548c2ecf20Sopenharmony_ci rc = kstrtouint_from_user(buf, count, 10, &value); 8558c2ecf20Sopenharmony_ci if (rc) 8568c2ecf20Sopenharmony_ci return rc; 8578c2ecf20Sopenharmony_ci 8588c2ecf20Sopenharmony_ci if (value == 1) { 8598c2ecf20Sopenharmony_ci pci_set_power_state(hdev->pdev, PCI_D0); 8608c2ecf20Sopenharmony_ci pci_restore_state(hdev->pdev); 8618c2ecf20Sopenharmony_ci rc = pci_enable_device(hdev->pdev); 8628c2ecf20Sopenharmony_ci if (rc < 0) 8638c2ecf20Sopenharmony_ci return rc; 8648c2ecf20Sopenharmony_ci } else if (value == 2) { 8658c2ecf20Sopenharmony_ci pci_save_state(hdev->pdev); 8668c2ecf20Sopenharmony_ci pci_disable_device(hdev->pdev); 8678c2ecf20Sopenharmony_ci pci_set_power_state(hdev->pdev, PCI_D3hot); 8688c2ecf20Sopenharmony_ci } else { 8698c2ecf20Sopenharmony_ci dev_dbg(hdev->dev, "invalid power state value %u\n", value); 8708c2ecf20Sopenharmony_ci return -EINVAL; 8718c2ecf20Sopenharmony_ci } 8728c2ecf20Sopenharmony_ci 8738c2ecf20Sopenharmony_ci return count; 8748c2ecf20Sopenharmony_ci} 8758c2ecf20Sopenharmony_ci 8768c2ecf20Sopenharmony_cistatic ssize_t hl_i2c_data_read(struct file *f, char __user *buf, 8778c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 8788c2ecf20Sopenharmony_ci{ 8798c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *entry = file_inode(f)->i_private; 8808c2ecf20Sopenharmony_ci struct hl_device *hdev = entry->hdev; 8818c2ecf20Sopenharmony_ci char tmp_buf[32]; 8828c2ecf20Sopenharmony_ci long val; 8838c2ecf20Sopenharmony_ci ssize_t rc; 8848c2ecf20Sopenharmony_ci 8858c2ecf20Sopenharmony_ci if (*ppos) 8868c2ecf20Sopenharmony_ci return 0; 8878c2ecf20Sopenharmony_ci 8888c2ecf20Sopenharmony_ci rc = hl_debugfs_i2c_read(hdev, entry->i2c_bus, entry->i2c_addr, 8898c2ecf20Sopenharmony_ci entry->i2c_reg, &val); 8908c2ecf20Sopenharmony_ci if (rc) { 8918c2ecf20Sopenharmony_ci dev_err(hdev->dev, 8928c2ecf20Sopenharmony_ci "Failed to read from I2C bus %d, addr %d, reg %d\n", 8938c2ecf20Sopenharmony_ci entry->i2c_bus, entry->i2c_addr, entry->i2c_reg); 8948c2ecf20Sopenharmony_ci return rc; 8958c2ecf20Sopenharmony_ci } 8968c2ecf20Sopenharmony_ci 8978c2ecf20Sopenharmony_ci sprintf(tmp_buf, "0x%02lx\n", val); 8988c2ecf20Sopenharmony_ci rc = simple_read_from_buffer(buf, count, ppos, tmp_buf, 8998c2ecf20Sopenharmony_ci strlen(tmp_buf)); 9008c2ecf20Sopenharmony_ci 9018c2ecf20Sopenharmony_ci return rc; 9028c2ecf20Sopenharmony_ci} 9038c2ecf20Sopenharmony_ci 9048c2ecf20Sopenharmony_cistatic ssize_t hl_i2c_data_write(struct file *f, const char __user *buf, 9058c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 9068c2ecf20Sopenharmony_ci{ 9078c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *entry = file_inode(f)->i_private; 9088c2ecf20Sopenharmony_ci struct hl_device *hdev = entry->hdev; 9098c2ecf20Sopenharmony_ci u32 value; 9108c2ecf20Sopenharmony_ci ssize_t rc; 9118c2ecf20Sopenharmony_ci 9128c2ecf20Sopenharmony_ci rc = kstrtouint_from_user(buf, count, 16, &value); 9138c2ecf20Sopenharmony_ci if (rc) 9148c2ecf20Sopenharmony_ci return rc; 9158c2ecf20Sopenharmony_ci 9168c2ecf20Sopenharmony_ci rc = hl_debugfs_i2c_write(hdev, entry->i2c_bus, entry->i2c_addr, 9178c2ecf20Sopenharmony_ci entry->i2c_reg, value); 9188c2ecf20Sopenharmony_ci if (rc) { 9198c2ecf20Sopenharmony_ci dev_err(hdev->dev, 9208c2ecf20Sopenharmony_ci "Failed to write 0x%02x to I2C bus %d, addr %d, reg %d\n", 9218c2ecf20Sopenharmony_ci value, entry->i2c_bus, entry->i2c_addr, entry->i2c_reg); 9228c2ecf20Sopenharmony_ci return rc; 9238c2ecf20Sopenharmony_ci } 9248c2ecf20Sopenharmony_ci 9258c2ecf20Sopenharmony_ci return count; 9268c2ecf20Sopenharmony_ci} 9278c2ecf20Sopenharmony_ci 9288c2ecf20Sopenharmony_cistatic ssize_t hl_led0_write(struct file *f, const char __user *buf, 9298c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 9308c2ecf20Sopenharmony_ci{ 9318c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *entry = file_inode(f)->i_private; 9328c2ecf20Sopenharmony_ci struct hl_device *hdev = entry->hdev; 9338c2ecf20Sopenharmony_ci u32 value; 9348c2ecf20Sopenharmony_ci ssize_t rc; 9358c2ecf20Sopenharmony_ci 9368c2ecf20Sopenharmony_ci rc = kstrtouint_from_user(buf, count, 10, &value); 9378c2ecf20Sopenharmony_ci if (rc) 9388c2ecf20Sopenharmony_ci return rc; 9398c2ecf20Sopenharmony_ci 9408c2ecf20Sopenharmony_ci value = value ? 1 : 0; 9418c2ecf20Sopenharmony_ci 9428c2ecf20Sopenharmony_ci hl_debugfs_led_set(hdev, 0, value); 9438c2ecf20Sopenharmony_ci 9448c2ecf20Sopenharmony_ci return count; 9458c2ecf20Sopenharmony_ci} 9468c2ecf20Sopenharmony_ci 9478c2ecf20Sopenharmony_cistatic ssize_t hl_led1_write(struct file *f, const char __user *buf, 9488c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 9498c2ecf20Sopenharmony_ci{ 9508c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *entry = file_inode(f)->i_private; 9518c2ecf20Sopenharmony_ci struct hl_device *hdev = entry->hdev; 9528c2ecf20Sopenharmony_ci u32 value; 9538c2ecf20Sopenharmony_ci ssize_t rc; 9548c2ecf20Sopenharmony_ci 9558c2ecf20Sopenharmony_ci rc = kstrtouint_from_user(buf, count, 10, &value); 9568c2ecf20Sopenharmony_ci if (rc) 9578c2ecf20Sopenharmony_ci return rc; 9588c2ecf20Sopenharmony_ci 9598c2ecf20Sopenharmony_ci value = value ? 1 : 0; 9608c2ecf20Sopenharmony_ci 9618c2ecf20Sopenharmony_ci hl_debugfs_led_set(hdev, 1, value); 9628c2ecf20Sopenharmony_ci 9638c2ecf20Sopenharmony_ci return count; 9648c2ecf20Sopenharmony_ci} 9658c2ecf20Sopenharmony_ci 9668c2ecf20Sopenharmony_cistatic ssize_t hl_led2_write(struct file *f, const char __user *buf, 9678c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 9688c2ecf20Sopenharmony_ci{ 9698c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *entry = file_inode(f)->i_private; 9708c2ecf20Sopenharmony_ci struct hl_device *hdev = entry->hdev; 9718c2ecf20Sopenharmony_ci u32 value; 9728c2ecf20Sopenharmony_ci ssize_t rc; 9738c2ecf20Sopenharmony_ci 9748c2ecf20Sopenharmony_ci rc = kstrtouint_from_user(buf, count, 10, &value); 9758c2ecf20Sopenharmony_ci if (rc) 9768c2ecf20Sopenharmony_ci return rc; 9778c2ecf20Sopenharmony_ci 9788c2ecf20Sopenharmony_ci value = value ? 1 : 0; 9798c2ecf20Sopenharmony_ci 9808c2ecf20Sopenharmony_ci hl_debugfs_led_set(hdev, 2, value); 9818c2ecf20Sopenharmony_ci 9828c2ecf20Sopenharmony_ci return count; 9838c2ecf20Sopenharmony_ci} 9848c2ecf20Sopenharmony_ci 9858c2ecf20Sopenharmony_cistatic ssize_t hl_device_read(struct file *f, char __user *buf, 9868c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 9878c2ecf20Sopenharmony_ci{ 9888c2ecf20Sopenharmony_ci static const char *help = 9898c2ecf20Sopenharmony_ci "Valid values: disable, enable, suspend, resume, cpu_timeout\n"; 9908c2ecf20Sopenharmony_ci return simple_read_from_buffer(buf, count, ppos, help, strlen(help)); 9918c2ecf20Sopenharmony_ci} 9928c2ecf20Sopenharmony_ci 9938c2ecf20Sopenharmony_cistatic ssize_t hl_device_write(struct file *f, const char __user *buf, 9948c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 9958c2ecf20Sopenharmony_ci{ 9968c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *entry = file_inode(f)->i_private; 9978c2ecf20Sopenharmony_ci struct hl_device *hdev = entry->hdev; 9988c2ecf20Sopenharmony_ci char data[30] = {0}; 9998c2ecf20Sopenharmony_ci 10008c2ecf20Sopenharmony_ci /* don't allow partial writes */ 10018c2ecf20Sopenharmony_ci if (*ppos != 0) 10028c2ecf20Sopenharmony_ci return 0; 10038c2ecf20Sopenharmony_ci 10048c2ecf20Sopenharmony_ci simple_write_to_buffer(data, 29, ppos, buf, count); 10058c2ecf20Sopenharmony_ci 10068c2ecf20Sopenharmony_ci if (strncmp("disable", data, strlen("disable")) == 0) { 10078c2ecf20Sopenharmony_ci hdev->disabled = true; 10088c2ecf20Sopenharmony_ci } else if (strncmp("enable", data, strlen("enable")) == 0) { 10098c2ecf20Sopenharmony_ci hdev->disabled = false; 10108c2ecf20Sopenharmony_ci } else if (strncmp("suspend", data, strlen("suspend")) == 0) { 10118c2ecf20Sopenharmony_ci hdev->asic_funcs->suspend(hdev); 10128c2ecf20Sopenharmony_ci } else if (strncmp("resume", data, strlen("resume")) == 0) { 10138c2ecf20Sopenharmony_ci hdev->asic_funcs->resume(hdev); 10148c2ecf20Sopenharmony_ci } else if (strncmp("cpu_timeout", data, strlen("cpu_timeout")) == 0) { 10158c2ecf20Sopenharmony_ci hdev->device_cpu_disabled = true; 10168c2ecf20Sopenharmony_ci } else { 10178c2ecf20Sopenharmony_ci dev_err(hdev->dev, 10188c2ecf20Sopenharmony_ci "Valid values: disable, enable, suspend, resume, cpu_timeout\n"); 10198c2ecf20Sopenharmony_ci count = -EINVAL; 10208c2ecf20Sopenharmony_ci } 10218c2ecf20Sopenharmony_ci 10228c2ecf20Sopenharmony_ci return count; 10238c2ecf20Sopenharmony_ci} 10248c2ecf20Sopenharmony_ci 10258c2ecf20Sopenharmony_cistatic ssize_t hl_clk_gate_read(struct file *f, char __user *buf, 10268c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 10278c2ecf20Sopenharmony_ci{ 10288c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *entry = file_inode(f)->i_private; 10298c2ecf20Sopenharmony_ci struct hl_device *hdev = entry->hdev; 10308c2ecf20Sopenharmony_ci char tmp_buf[200]; 10318c2ecf20Sopenharmony_ci ssize_t rc; 10328c2ecf20Sopenharmony_ci 10338c2ecf20Sopenharmony_ci if (*ppos) 10348c2ecf20Sopenharmony_ci return 0; 10358c2ecf20Sopenharmony_ci 10368c2ecf20Sopenharmony_ci sprintf(tmp_buf, "0x%llx\n", hdev->clock_gating_mask); 10378c2ecf20Sopenharmony_ci rc = simple_read_from_buffer(buf, count, ppos, tmp_buf, 10388c2ecf20Sopenharmony_ci strlen(tmp_buf) + 1); 10398c2ecf20Sopenharmony_ci 10408c2ecf20Sopenharmony_ci return rc; 10418c2ecf20Sopenharmony_ci} 10428c2ecf20Sopenharmony_ci 10438c2ecf20Sopenharmony_cistatic ssize_t hl_clk_gate_write(struct file *f, const char __user *buf, 10448c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 10458c2ecf20Sopenharmony_ci{ 10468c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *entry = file_inode(f)->i_private; 10478c2ecf20Sopenharmony_ci struct hl_device *hdev = entry->hdev; 10488c2ecf20Sopenharmony_ci u64 value; 10498c2ecf20Sopenharmony_ci ssize_t rc; 10508c2ecf20Sopenharmony_ci 10518c2ecf20Sopenharmony_ci if (atomic_read(&hdev->in_reset)) { 10528c2ecf20Sopenharmony_ci dev_warn_ratelimited(hdev->dev, 10538c2ecf20Sopenharmony_ci "Can't change clock gating during reset\n"); 10548c2ecf20Sopenharmony_ci return 0; 10558c2ecf20Sopenharmony_ci } 10568c2ecf20Sopenharmony_ci 10578c2ecf20Sopenharmony_ci rc = kstrtoull_from_user(buf, count, 16, &value); 10588c2ecf20Sopenharmony_ci if (rc) 10598c2ecf20Sopenharmony_ci return rc; 10608c2ecf20Sopenharmony_ci 10618c2ecf20Sopenharmony_ci hdev->clock_gating_mask = value; 10628c2ecf20Sopenharmony_ci hdev->asic_funcs->set_clock_gating(hdev); 10638c2ecf20Sopenharmony_ci 10648c2ecf20Sopenharmony_ci return count; 10658c2ecf20Sopenharmony_ci} 10668c2ecf20Sopenharmony_ci 10678c2ecf20Sopenharmony_cistatic ssize_t hl_stop_on_err_read(struct file *f, char __user *buf, 10688c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 10698c2ecf20Sopenharmony_ci{ 10708c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *entry = file_inode(f)->i_private; 10718c2ecf20Sopenharmony_ci struct hl_device *hdev = entry->hdev; 10728c2ecf20Sopenharmony_ci char tmp_buf[200]; 10738c2ecf20Sopenharmony_ci ssize_t rc; 10748c2ecf20Sopenharmony_ci 10758c2ecf20Sopenharmony_ci if (*ppos) 10768c2ecf20Sopenharmony_ci return 0; 10778c2ecf20Sopenharmony_ci 10788c2ecf20Sopenharmony_ci sprintf(tmp_buf, "%d\n", hdev->stop_on_err); 10798c2ecf20Sopenharmony_ci rc = simple_read_from_buffer(buf, strlen(tmp_buf) + 1, ppos, tmp_buf, 10808c2ecf20Sopenharmony_ci strlen(tmp_buf) + 1); 10818c2ecf20Sopenharmony_ci 10828c2ecf20Sopenharmony_ci return rc; 10838c2ecf20Sopenharmony_ci} 10848c2ecf20Sopenharmony_ci 10858c2ecf20Sopenharmony_cistatic ssize_t hl_stop_on_err_write(struct file *f, const char __user *buf, 10868c2ecf20Sopenharmony_ci size_t count, loff_t *ppos) 10878c2ecf20Sopenharmony_ci{ 10888c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *entry = file_inode(f)->i_private; 10898c2ecf20Sopenharmony_ci struct hl_device *hdev = entry->hdev; 10908c2ecf20Sopenharmony_ci u32 value; 10918c2ecf20Sopenharmony_ci ssize_t rc; 10928c2ecf20Sopenharmony_ci 10938c2ecf20Sopenharmony_ci if (atomic_read(&hdev->in_reset)) { 10948c2ecf20Sopenharmony_ci dev_warn_ratelimited(hdev->dev, 10958c2ecf20Sopenharmony_ci "Can't change stop on error during reset\n"); 10968c2ecf20Sopenharmony_ci return 0; 10978c2ecf20Sopenharmony_ci } 10988c2ecf20Sopenharmony_ci 10998c2ecf20Sopenharmony_ci rc = kstrtouint_from_user(buf, count, 10, &value); 11008c2ecf20Sopenharmony_ci if (rc) 11018c2ecf20Sopenharmony_ci return rc; 11028c2ecf20Sopenharmony_ci 11038c2ecf20Sopenharmony_ci hdev->stop_on_err = value ? 1 : 0; 11048c2ecf20Sopenharmony_ci 11058c2ecf20Sopenharmony_ci hl_device_reset(hdev, false, false); 11068c2ecf20Sopenharmony_ci 11078c2ecf20Sopenharmony_ci return count; 11088c2ecf20Sopenharmony_ci} 11098c2ecf20Sopenharmony_ci 11108c2ecf20Sopenharmony_cistatic const struct file_operations hl_data32b_fops = { 11118c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 11128c2ecf20Sopenharmony_ci .read = hl_data_read32, 11138c2ecf20Sopenharmony_ci .write = hl_data_write32 11148c2ecf20Sopenharmony_ci}; 11158c2ecf20Sopenharmony_ci 11168c2ecf20Sopenharmony_cistatic const struct file_operations hl_data64b_fops = { 11178c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 11188c2ecf20Sopenharmony_ci .read = hl_data_read64, 11198c2ecf20Sopenharmony_ci .write = hl_data_write64 11208c2ecf20Sopenharmony_ci}; 11218c2ecf20Sopenharmony_ci 11228c2ecf20Sopenharmony_cistatic const struct file_operations hl_i2c_data_fops = { 11238c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 11248c2ecf20Sopenharmony_ci .read = hl_i2c_data_read, 11258c2ecf20Sopenharmony_ci .write = hl_i2c_data_write 11268c2ecf20Sopenharmony_ci}; 11278c2ecf20Sopenharmony_ci 11288c2ecf20Sopenharmony_cistatic const struct file_operations hl_power_fops = { 11298c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 11308c2ecf20Sopenharmony_ci .read = hl_get_power_state, 11318c2ecf20Sopenharmony_ci .write = hl_set_power_state 11328c2ecf20Sopenharmony_ci}; 11338c2ecf20Sopenharmony_ci 11348c2ecf20Sopenharmony_cistatic const struct file_operations hl_led0_fops = { 11358c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 11368c2ecf20Sopenharmony_ci .write = hl_led0_write 11378c2ecf20Sopenharmony_ci}; 11388c2ecf20Sopenharmony_ci 11398c2ecf20Sopenharmony_cistatic const struct file_operations hl_led1_fops = { 11408c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 11418c2ecf20Sopenharmony_ci .write = hl_led1_write 11428c2ecf20Sopenharmony_ci}; 11438c2ecf20Sopenharmony_ci 11448c2ecf20Sopenharmony_cistatic const struct file_operations hl_led2_fops = { 11458c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 11468c2ecf20Sopenharmony_ci .write = hl_led2_write 11478c2ecf20Sopenharmony_ci}; 11488c2ecf20Sopenharmony_ci 11498c2ecf20Sopenharmony_cistatic const struct file_operations hl_device_fops = { 11508c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 11518c2ecf20Sopenharmony_ci .read = hl_device_read, 11528c2ecf20Sopenharmony_ci .write = hl_device_write 11538c2ecf20Sopenharmony_ci}; 11548c2ecf20Sopenharmony_ci 11558c2ecf20Sopenharmony_cistatic const struct file_operations hl_clk_gate_fops = { 11568c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 11578c2ecf20Sopenharmony_ci .read = hl_clk_gate_read, 11588c2ecf20Sopenharmony_ci .write = hl_clk_gate_write 11598c2ecf20Sopenharmony_ci}; 11608c2ecf20Sopenharmony_ci 11618c2ecf20Sopenharmony_cistatic const struct file_operations hl_stop_on_err_fops = { 11628c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 11638c2ecf20Sopenharmony_ci .read = hl_stop_on_err_read, 11648c2ecf20Sopenharmony_ci .write = hl_stop_on_err_write 11658c2ecf20Sopenharmony_ci}; 11668c2ecf20Sopenharmony_ci 11678c2ecf20Sopenharmony_cistatic const struct hl_info_list hl_debugfs_list[] = { 11688c2ecf20Sopenharmony_ci {"command_buffers", command_buffers_show, NULL}, 11698c2ecf20Sopenharmony_ci {"command_submission", command_submission_show, NULL}, 11708c2ecf20Sopenharmony_ci {"command_submission_jobs", command_submission_jobs_show, NULL}, 11718c2ecf20Sopenharmony_ci {"userptr", userptr_show, NULL}, 11728c2ecf20Sopenharmony_ci {"vm", vm_show, NULL}, 11738c2ecf20Sopenharmony_ci {"mmu", mmu_show, mmu_asid_va_write}, 11748c2ecf20Sopenharmony_ci {"engines", engines_show, NULL} 11758c2ecf20Sopenharmony_ci}; 11768c2ecf20Sopenharmony_ci 11778c2ecf20Sopenharmony_cistatic int hl_debugfs_open(struct inode *inode, struct file *file) 11788c2ecf20Sopenharmony_ci{ 11798c2ecf20Sopenharmony_ci struct hl_debugfs_entry *node = inode->i_private; 11808c2ecf20Sopenharmony_ci 11818c2ecf20Sopenharmony_ci return single_open(file, node->info_ent->show, node); 11828c2ecf20Sopenharmony_ci} 11838c2ecf20Sopenharmony_ci 11848c2ecf20Sopenharmony_cistatic ssize_t hl_debugfs_write(struct file *file, const char __user *buf, 11858c2ecf20Sopenharmony_ci size_t count, loff_t *f_pos) 11868c2ecf20Sopenharmony_ci{ 11878c2ecf20Sopenharmony_ci struct hl_debugfs_entry *node = file->f_inode->i_private; 11888c2ecf20Sopenharmony_ci 11898c2ecf20Sopenharmony_ci if (node->info_ent->write) 11908c2ecf20Sopenharmony_ci return node->info_ent->write(file, buf, count, f_pos); 11918c2ecf20Sopenharmony_ci else 11928c2ecf20Sopenharmony_ci return -EINVAL; 11938c2ecf20Sopenharmony_ci 11948c2ecf20Sopenharmony_ci} 11958c2ecf20Sopenharmony_ci 11968c2ecf20Sopenharmony_cistatic const struct file_operations hl_debugfs_fops = { 11978c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 11988c2ecf20Sopenharmony_ci .open = hl_debugfs_open, 11998c2ecf20Sopenharmony_ci .read = seq_read, 12008c2ecf20Sopenharmony_ci .write = hl_debugfs_write, 12018c2ecf20Sopenharmony_ci .llseek = seq_lseek, 12028c2ecf20Sopenharmony_ci .release = single_release, 12038c2ecf20Sopenharmony_ci}; 12048c2ecf20Sopenharmony_ci 12058c2ecf20Sopenharmony_civoid hl_debugfs_add_device(struct hl_device *hdev) 12068c2ecf20Sopenharmony_ci{ 12078c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs; 12088c2ecf20Sopenharmony_ci int count = ARRAY_SIZE(hl_debugfs_list); 12098c2ecf20Sopenharmony_ci struct hl_debugfs_entry *entry; 12108c2ecf20Sopenharmony_ci struct dentry *ent; 12118c2ecf20Sopenharmony_ci int i; 12128c2ecf20Sopenharmony_ci 12138c2ecf20Sopenharmony_ci dev_entry->hdev = hdev; 12148c2ecf20Sopenharmony_ci dev_entry->entry_arr = kmalloc_array(count, 12158c2ecf20Sopenharmony_ci sizeof(struct hl_debugfs_entry), 12168c2ecf20Sopenharmony_ci GFP_KERNEL); 12178c2ecf20Sopenharmony_ci if (!dev_entry->entry_arr) 12188c2ecf20Sopenharmony_ci return; 12198c2ecf20Sopenharmony_ci 12208c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&dev_entry->file_list); 12218c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&dev_entry->cb_list); 12228c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&dev_entry->cs_list); 12238c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&dev_entry->cs_job_list); 12248c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&dev_entry->userptr_list); 12258c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&dev_entry->ctx_mem_hash_list); 12268c2ecf20Sopenharmony_ci mutex_init(&dev_entry->file_mutex); 12278c2ecf20Sopenharmony_ci spin_lock_init(&dev_entry->cb_spinlock); 12288c2ecf20Sopenharmony_ci spin_lock_init(&dev_entry->cs_spinlock); 12298c2ecf20Sopenharmony_ci spin_lock_init(&dev_entry->cs_job_spinlock); 12308c2ecf20Sopenharmony_ci spin_lock_init(&dev_entry->userptr_spinlock); 12318c2ecf20Sopenharmony_ci spin_lock_init(&dev_entry->ctx_mem_hash_spinlock); 12328c2ecf20Sopenharmony_ci 12338c2ecf20Sopenharmony_ci dev_entry->root = debugfs_create_dir(dev_name(hdev->dev), 12348c2ecf20Sopenharmony_ci hl_debug_root); 12358c2ecf20Sopenharmony_ci 12368c2ecf20Sopenharmony_ci debugfs_create_x64("addr", 12378c2ecf20Sopenharmony_ci 0644, 12388c2ecf20Sopenharmony_ci dev_entry->root, 12398c2ecf20Sopenharmony_ci &dev_entry->addr); 12408c2ecf20Sopenharmony_ci 12418c2ecf20Sopenharmony_ci debugfs_create_file("data32", 12428c2ecf20Sopenharmony_ci 0644, 12438c2ecf20Sopenharmony_ci dev_entry->root, 12448c2ecf20Sopenharmony_ci dev_entry, 12458c2ecf20Sopenharmony_ci &hl_data32b_fops); 12468c2ecf20Sopenharmony_ci 12478c2ecf20Sopenharmony_ci debugfs_create_file("data64", 12488c2ecf20Sopenharmony_ci 0644, 12498c2ecf20Sopenharmony_ci dev_entry->root, 12508c2ecf20Sopenharmony_ci dev_entry, 12518c2ecf20Sopenharmony_ci &hl_data64b_fops); 12528c2ecf20Sopenharmony_ci 12538c2ecf20Sopenharmony_ci debugfs_create_file("set_power_state", 12548c2ecf20Sopenharmony_ci 0200, 12558c2ecf20Sopenharmony_ci dev_entry->root, 12568c2ecf20Sopenharmony_ci dev_entry, 12578c2ecf20Sopenharmony_ci &hl_power_fops); 12588c2ecf20Sopenharmony_ci 12598c2ecf20Sopenharmony_ci debugfs_create_u8("i2c_bus", 12608c2ecf20Sopenharmony_ci 0644, 12618c2ecf20Sopenharmony_ci dev_entry->root, 12628c2ecf20Sopenharmony_ci &dev_entry->i2c_bus); 12638c2ecf20Sopenharmony_ci 12648c2ecf20Sopenharmony_ci debugfs_create_u8("i2c_addr", 12658c2ecf20Sopenharmony_ci 0644, 12668c2ecf20Sopenharmony_ci dev_entry->root, 12678c2ecf20Sopenharmony_ci &dev_entry->i2c_addr); 12688c2ecf20Sopenharmony_ci 12698c2ecf20Sopenharmony_ci debugfs_create_u8("i2c_reg", 12708c2ecf20Sopenharmony_ci 0644, 12718c2ecf20Sopenharmony_ci dev_entry->root, 12728c2ecf20Sopenharmony_ci &dev_entry->i2c_reg); 12738c2ecf20Sopenharmony_ci 12748c2ecf20Sopenharmony_ci debugfs_create_file("i2c_data", 12758c2ecf20Sopenharmony_ci 0644, 12768c2ecf20Sopenharmony_ci dev_entry->root, 12778c2ecf20Sopenharmony_ci dev_entry, 12788c2ecf20Sopenharmony_ci &hl_i2c_data_fops); 12798c2ecf20Sopenharmony_ci 12808c2ecf20Sopenharmony_ci debugfs_create_file("led0", 12818c2ecf20Sopenharmony_ci 0200, 12828c2ecf20Sopenharmony_ci dev_entry->root, 12838c2ecf20Sopenharmony_ci dev_entry, 12848c2ecf20Sopenharmony_ci &hl_led0_fops); 12858c2ecf20Sopenharmony_ci 12868c2ecf20Sopenharmony_ci debugfs_create_file("led1", 12878c2ecf20Sopenharmony_ci 0200, 12888c2ecf20Sopenharmony_ci dev_entry->root, 12898c2ecf20Sopenharmony_ci dev_entry, 12908c2ecf20Sopenharmony_ci &hl_led1_fops); 12918c2ecf20Sopenharmony_ci 12928c2ecf20Sopenharmony_ci debugfs_create_file("led2", 12938c2ecf20Sopenharmony_ci 0200, 12948c2ecf20Sopenharmony_ci dev_entry->root, 12958c2ecf20Sopenharmony_ci dev_entry, 12968c2ecf20Sopenharmony_ci &hl_led2_fops); 12978c2ecf20Sopenharmony_ci 12988c2ecf20Sopenharmony_ci debugfs_create_file("device", 12998c2ecf20Sopenharmony_ci 0200, 13008c2ecf20Sopenharmony_ci dev_entry->root, 13018c2ecf20Sopenharmony_ci dev_entry, 13028c2ecf20Sopenharmony_ci &hl_device_fops); 13038c2ecf20Sopenharmony_ci 13048c2ecf20Sopenharmony_ci debugfs_create_file("clk_gate", 13058c2ecf20Sopenharmony_ci 0200, 13068c2ecf20Sopenharmony_ci dev_entry->root, 13078c2ecf20Sopenharmony_ci dev_entry, 13088c2ecf20Sopenharmony_ci &hl_clk_gate_fops); 13098c2ecf20Sopenharmony_ci 13108c2ecf20Sopenharmony_ci debugfs_create_file("stop_on_err", 13118c2ecf20Sopenharmony_ci 0644, 13128c2ecf20Sopenharmony_ci dev_entry->root, 13138c2ecf20Sopenharmony_ci dev_entry, 13148c2ecf20Sopenharmony_ci &hl_stop_on_err_fops); 13158c2ecf20Sopenharmony_ci 13168c2ecf20Sopenharmony_ci for (i = 0, entry = dev_entry->entry_arr ; i < count ; i++, entry++) { 13178c2ecf20Sopenharmony_ci 13188c2ecf20Sopenharmony_ci ent = debugfs_create_file(hl_debugfs_list[i].name, 13198c2ecf20Sopenharmony_ci 0444, 13208c2ecf20Sopenharmony_ci dev_entry->root, 13218c2ecf20Sopenharmony_ci entry, 13228c2ecf20Sopenharmony_ci &hl_debugfs_fops); 13238c2ecf20Sopenharmony_ci entry->dent = ent; 13248c2ecf20Sopenharmony_ci entry->info_ent = &hl_debugfs_list[i]; 13258c2ecf20Sopenharmony_ci entry->dev_entry = dev_entry; 13268c2ecf20Sopenharmony_ci } 13278c2ecf20Sopenharmony_ci} 13288c2ecf20Sopenharmony_ci 13298c2ecf20Sopenharmony_civoid hl_debugfs_remove_device(struct hl_device *hdev) 13308c2ecf20Sopenharmony_ci{ 13318c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *entry = &hdev->hl_debugfs; 13328c2ecf20Sopenharmony_ci 13338c2ecf20Sopenharmony_ci debugfs_remove_recursive(entry->root); 13348c2ecf20Sopenharmony_ci 13358c2ecf20Sopenharmony_ci mutex_destroy(&entry->file_mutex); 13368c2ecf20Sopenharmony_ci kfree(entry->entry_arr); 13378c2ecf20Sopenharmony_ci} 13388c2ecf20Sopenharmony_ci 13398c2ecf20Sopenharmony_civoid hl_debugfs_add_file(struct hl_fpriv *hpriv) 13408c2ecf20Sopenharmony_ci{ 13418c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *dev_entry = &hpriv->hdev->hl_debugfs; 13428c2ecf20Sopenharmony_ci 13438c2ecf20Sopenharmony_ci mutex_lock(&dev_entry->file_mutex); 13448c2ecf20Sopenharmony_ci list_add(&hpriv->debugfs_list, &dev_entry->file_list); 13458c2ecf20Sopenharmony_ci mutex_unlock(&dev_entry->file_mutex); 13468c2ecf20Sopenharmony_ci} 13478c2ecf20Sopenharmony_ci 13488c2ecf20Sopenharmony_civoid hl_debugfs_remove_file(struct hl_fpriv *hpriv) 13498c2ecf20Sopenharmony_ci{ 13508c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *dev_entry = &hpriv->hdev->hl_debugfs; 13518c2ecf20Sopenharmony_ci 13528c2ecf20Sopenharmony_ci mutex_lock(&dev_entry->file_mutex); 13538c2ecf20Sopenharmony_ci list_del(&hpriv->debugfs_list); 13548c2ecf20Sopenharmony_ci mutex_unlock(&dev_entry->file_mutex); 13558c2ecf20Sopenharmony_ci} 13568c2ecf20Sopenharmony_ci 13578c2ecf20Sopenharmony_civoid hl_debugfs_add_cb(struct hl_cb *cb) 13588c2ecf20Sopenharmony_ci{ 13598c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *dev_entry = &cb->hdev->hl_debugfs; 13608c2ecf20Sopenharmony_ci 13618c2ecf20Sopenharmony_ci spin_lock(&dev_entry->cb_spinlock); 13628c2ecf20Sopenharmony_ci list_add(&cb->debugfs_list, &dev_entry->cb_list); 13638c2ecf20Sopenharmony_ci spin_unlock(&dev_entry->cb_spinlock); 13648c2ecf20Sopenharmony_ci} 13658c2ecf20Sopenharmony_ci 13668c2ecf20Sopenharmony_civoid hl_debugfs_remove_cb(struct hl_cb *cb) 13678c2ecf20Sopenharmony_ci{ 13688c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *dev_entry = &cb->hdev->hl_debugfs; 13698c2ecf20Sopenharmony_ci 13708c2ecf20Sopenharmony_ci spin_lock(&dev_entry->cb_spinlock); 13718c2ecf20Sopenharmony_ci list_del(&cb->debugfs_list); 13728c2ecf20Sopenharmony_ci spin_unlock(&dev_entry->cb_spinlock); 13738c2ecf20Sopenharmony_ci} 13748c2ecf20Sopenharmony_ci 13758c2ecf20Sopenharmony_civoid hl_debugfs_add_cs(struct hl_cs *cs) 13768c2ecf20Sopenharmony_ci{ 13778c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *dev_entry = &cs->ctx->hdev->hl_debugfs; 13788c2ecf20Sopenharmony_ci 13798c2ecf20Sopenharmony_ci spin_lock(&dev_entry->cs_spinlock); 13808c2ecf20Sopenharmony_ci list_add(&cs->debugfs_list, &dev_entry->cs_list); 13818c2ecf20Sopenharmony_ci spin_unlock(&dev_entry->cs_spinlock); 13828c2ecf20Sopenharmony_ci} 13838c2ecf20Sopenharmony_ci 13848c2ecf20Sopenharmony_civoid hl_debugfs_remove_cs(struct hl_cs *cs) 13858c2ecf20Sopenharmony_ci{ 13868c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *dev_entry = &cs->ctx->hdev->hl_debugfs; 13878c2ecf20Sopenharmony_ci 13888c2ecf20Sopenharmony_ci spin_lock(&dev_entry->cs_spinlock); 13898c2ecf20Sopenharmony_ci list_del(&cs->debugfs_list); 13908c2ecf20Sopenharmony_ci spin_unlock(&dev_entry->cs_spinlock); 13918c2ecf20Sopenharmony_ci} 13928c2ecf20Sopenharmony_ci 13938c2ecf20Sopenharmony_civoid hl_debugfs_add_job(struct hl_device *hdev, struct hl_cs_job *job) 13948c2ecf20Sopenharmony_ci{ 13958c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs; 13968c2ecf20Sopenharmony_ci 13978c2ecf20Sopenharmony_ci spin_lock(&dev_entry->cs_job_spinlock); 13988c2ecf20Sopenharmony_ci list_add(&job->debugfs_list, &dev_entry->cs_job_list); 13998c2ecf20Sopenharmony_ci spin_unlock(&dev_entry->cs_job_spinlock); 14008c2ecf20Sopenharmony_ci} 14018c2ecf20Sopenharmony_ci 14028c2ecf20Sopenharmony_civoid hl_debugfs_remove_job(struct hl_device *hdev, struct hl_cs_job *job) 14038c2ecf20Sopenharmony_ci{ 14048c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs; 14058c2ecf20Sopenharmony_ci 14068c2ecf20Sopenharmony_ci spin_lock(&dev_entry->cs_job_spinlock); 14078c2ecf20Sopenharmony_ci list_del(&job->debugfs_list); 14088c2ecf20Sopenharmony_ci spin_unlock(&dev_entry->cs_job_spinlock); 14098c2ecf20Sopenharmony_ci} 14108c2ecf20Sopenharmony_ci 14118c2ecf20Sopenharmony_civoid hl_debugfs_add_userptr(struct hl_device *hdev, struct hl_userptr *userptr) 14128c2ecf20Sopenharmony_ci{ 14138c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs; 14148c2ecf20Sopenharmony_ci 14158c2ecf20Sopenharmony_ci spin_lock(&dev_entry->userptr_spinlock); 14168c2ecf20Sopenharmony_ci list_add(&userptr->debugfs_list, &dev_entry->userptr_list); 14178c2ecf20Sopenharmony_ci spin_unlock(&dev_entry->userptr_spinlock); 14188c2ecf20Sopenharmony_ci} 14198c2ecf20Sopenharmony_ci 14208c2ecf20Sopenharmony_civoid hl_debugfs_remove_userptr(struct hl_device *hdev, 14218c2ecf20Sopenharmony_ci struct hl_userptr *userptr) 14228c2ecf20Sopenharmony_ci{ 14238c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs; 14248c2ecf20Sopenharmony_ci 14258c2ecf20Sopenharmony_ci spin_lock(&dev_entry->userptr_spinlock); 14268c2ecf20Sopenharmony_ci list_del(&userptr->debugfs_list); 14278c2ecf20Sopenharmony_ci spin_unlock(&dev_entry->userptr_spinlock); 14288c2ecf20Sopenharmony_ci} 14298c2ecf20Sopenharmony_ci 14308c2ecf20Sopenharmony_civoid hl_debugfs_add_ctx_mem_hash(struct hl_device *hdev, struct hl_ctx *ctx) 14318c2ecf20Sopenharmony_ci{ 14328c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs; 14338c2ecf20Sopenharmony_ci 14348c2ecf20Sopenharmony_ci spin_lock(&dev_entry->ctx_mem_hash_spinlock); 14358c2ecf20Sopenharmony_ci list_add(&ctx->debugfs_list, &dev_entry->ctx_mem_hash_list); 14368c2ecf20Sopenharmony_ci spin_unlock(&dev_entry->ctx_mem_hash_spinlock); 14378c2ecf20Sopenharmony_ci} 14388c2ecf20Sopenharmony_ci 14398c2ecf20Sopenharmony_civoid hl_debugfs_remove_ctx_mem_hash(struct hl_device *hdev, struct hl_ctx *ctx) 14408c2ecf20Sopenharmony_ci{ 14418c2ecf20Sopenharmony_ci struct hl_dbg_device_entry *dev_entry = &hdev->hl_debugfs; 14428c2ecf20Sopenharmony_ci 14438c2ecf20Sopenharmony_ci spin_lock(&dev_entry->ctx_mem_hash_spinlock); 14448c2ecf20Sopenharmony_ci list_del(&ctx->debugfs_list); 14458c2ecf20Sopenharmony_ci spin_unlock(&dev_entry->ctx_mem_hash_spinlock); 14468c2ecf20Sopenharmony_ci} 14478c2ecf20Sopenharmony_ci 14488c2ecf20Sopenharmony_civoid __init hl_debugfs_init(void) 14498c2ecf20Sopenharmony_ci{ 14508c2ecf20Sopenharmony_ci hl_debug_root = debugfs_create_dir("habanalabs", NULL); 14518c2ecf20Sopenharmony_ci} 14528c2ecf20Sopenharmony_ci 14538c2ecf20Sopenharmony_civoid hl_debugfs_fini(void) 14548c2ecf20Sopenharmony_ci{ 14558c2ecf20Sopenharmony_ci debugfs_remove_recursive(hl_debug_root); 14568c2ecf20Sopenharmony_ci} 1457