1ece4e512SSukadev Bhattiprolu /* 2ece4e512SSukadev Bhattiprolu * Copyright 2016-17 IBM Corp. 3ece4e512SSukadev Bhattiprolu * 4ece4e512SSukadev Bhattiprolu * This program is free software; you can redistribute it and/or 5ece4e512SSukadev Bhattiprolu * modify it under the terms of the GNU General Public License 6ece4e512SSukadev Bhattiprolu * as published by the Free Software Foundation; either version 7ece4e512SSukadev Bhattiprolu * 2 of the License, or (at your option) any later version. 8ece4e512SSukadev Bhattiprolu */ 9ece4e512SSukadev Bhattiprolu 10ece4e512SSukadev Bhattiprolu #define pr_fmt(fmt) "vas: " fmt 11ece4e512SSukadev Bhattiprolu 12ece4e512SSukadev Bhattiprolu #include <linux/types.h> 13ece4e512SSukadev Bhattiprolu #include <linux/slab.h> 14ece4e512SSukadev Bhattiprolu #include <linux/debugfs.h> 15ece4e512SSukadev Bhattiprolu #include <linux/seq_file.h> 16ece4e512SSukadev Bhattiprolu #include "vas.h" 17ece4e512SSukadev Bhattiprolu 18ece4e512SSukadev Bhattiprolu static struct dentry *vas_debugfs; 19ece4e512SSukadev Bhattiprolu 20ece4e512SSukadev Bhattiprolu static char *cop_to_str(int cop) 21ece4e512SSukadev Bhattiprolu { 22ece4e512SSukadev Bhattiprolu switch (cop) { 23ece4e512SSukadev Bhattiprolu case VAS_COP_TYPE_FAULT: return "Fault"; 24ece4e512SSukadev Bhattiprolu case VAS_COP_TYPE_842: return "NX-842 Normal Priority"; 25ece4e512SSukadev Bhattiprolu case VAS_COP_TYPE_842_HIPRI: return "NX-842 High Priority"; 26ece4e512SSukadev Bhattiprolu case VAS_COP_TYPE_GZIP: return "NX-GZIP Normal Priority"; 27ece4e512SSukadev Bhattiprolu case VAS_COP_TYPE_GZIP_HIPRI: return "NX-GZIP High Priority"; 28ece4e512SSukadev Bhattiprolu case VAS_COP_TYPE_FTW: return "Fast Thread-wakeup"; 29ece4e512SSukadev Bhattiprolu default: return "Unknown"; 30ece4e512SSukadev Bhattiprolu } 31ece4e512SSukadev Bhattiprolu } 32ece4e512SSukadev Bhattiprolu 33ece4e512SSukadev Bhattiprolu static int info_dbg_show(struct seq_file *s, void *private) 34ece4e512SSukadev Bhattiprolu { 35ece4e512SSukadev Bhattiprolu struct vas_window *window = s->private; 36ece4e512SSukadev Bhattiprolu 37ece4e512SSukadev Bhattiprolu mutex_lock(&vas_mutex); 38ece4e512SSukadev Bhattiprolu 39ece4e512SSukadev Bhattiprolu /* ensure window is not unmapped */ 40ece4e512SSukadev Bhattiprolu if (!window->hvwc_map) 41ece4e512SSukadev Bhattiprolu goto unlock; 42ece4e512SSukadev Bhattiprolu 43ece4e512SSukadev Bhattiprolu seq_printf(s, "Type: %s, %s\n", cop_to_str(window->cop), 44ece4e512SSukadev Bhattiprolu window->tx_win ? "Send" : "Receive"); 45ece4e512SSukadev Bhattiprolu seq_printf(s, "Pid : %d\n", window->pid); 46ece4e512SSukadev Bhattiprolu 47ece4e512SSukadev Bhattiprolu unlock: 48ece4e512SSukadev Bhattiprolu mutex_unlock(&vas_mutex); 49ece4e512SSukadev Bhattiprolu return 0; 50ece4e512SSukadev Bhattiprolu } 51ece4e512SSukadev Bhattiprolu 52ece4e512SSukadev Bhattiprolu static int info_dbg_open(struct inode *inode, struct file *file) 53ece4e512SSukadev Bhattiprolu { 54ece4e512SSukadev Bhattiprolu return single_open(file, info_dbg_show, inode->i_private); 55ece4e512SSukadev Bhattiprolu } 56ece4e512SSukadev Bhattiprolu 57ece4e512SSukadev Bhattiprolu static const struct file_operations info_fops = { 58ece4e512SSukadev Bhattiprolu .open = info_dbg_open, 59ece4e512SSukadev Bhattiprolu .read = seq_read, 60ece4e512SSukadev Bhattiprolu .llseek = seq_lseek, 61ece4e512SSukadev Bhattiprolu .release = single_release, 62ece4e512SSukadev Bhattiprolu }; 63ece4e512SSukadev Bhattiprolu 64ece4e512SSukadev Bhattiprolu static inline void print_reg(struct seq_file *s, struct vas_window *win, 65ece4e512SSukadev Bhattiprolu char *name, u32 reg) 66ece4e512SSukadev Bhattiprolu { 67ece4e512SSukadev Bhattiprolu seq_printf(s, "0x%016llx %s\n", read_hvwc_reg(win, name, reg), name); 68ece4e512SSukadev Bhattiprolu } 69ece4e512SSukadev Bhattiprolu 70ece4e512SSukadev Bhattiprolu static int hvwc_dbg_show(struct seq_file *s, void *private) 71ece4e512SSukadev Bhattiprolu { 72ece4e512SSukadev Bhattiprolu struct vas_window *window = s->private; 73ece4e512SSukadev Bhattiprolu 74ece4e512SSukadev Bhattiprolu mutex_lock(&vas_mutex); 75ece4e512SSukadev Bhattiprolu 76ece4e512SSukadev Bhattiprolu /* ensure window is not unmapped */ 77ece4e512SSukadev Bhattiprolu if (!window->hvwc_map) 78ece4e512SSukadev Bhattiprolu goto unlock; 79ece4e512SSukadev Bhattiprolu 80ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(LPID)); 81ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(PID)); 82ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(XLATE_MSR)); 83ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(XLATE_LPCR)); 84ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(XLATE_CTL)); 85ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(AMR)); 86ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(SEIDR)); 87ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(FAULT_TX_WIN)); 88ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(OSU_INTR_SRC_RA)); 89ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(HV_INTR_SRC_RA)); 90ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(PSWID)); 91ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(LFIFO_BAR)); 92ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(LDATA_STAMP_CTL)); 93ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(LDMA_CACHE_CTL)); 94ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(LRFIFO_PUSH)); 95ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(CURR_MSG_COUNT)); 96ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(LNOTIFY_AFTER_COUNT)); 97ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(LRX_WCRED)); 98ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(LRX_WCRED_ADDER)); 99ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(TX_WCRED)); 100ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(TX_WCRED_ADDER)); 101ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(LFIFO_SIZE)); 102ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(WINCTL)); 103ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(WIN_STATUS)); 104ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(WIN_CTX_CACHING_CTL)); 105ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(TX_RSVD_BUF_COUNT)); 106ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(LRFIFO_WIN_PTR)); 107ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(LNOTIFY_CTL)); 108ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(LNOTIFY_PID)); 109ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(LNOTIFY_LPID)); 110ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(LNOTIFY_TID)); 111ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(LNOTIFY_SCOPE)); 112ece4e512SSukadev Bhattiprolu print_reg(s, window, VREG(NX_UTIL_ADDER)); 113ece4e512SSukadev Bhattiprolu unlock: 114ece4e512SSukadev Bhattiprolu mutex_unlock(&vas_mutex); 115ece4e512SSukadev Bhattiprolu return 0; 116ece4e512SSukadev Bhattiprolu } 117ece4e512SSukadev Bhattiprolu 118ece4e512SSukadev Bhattiprolu static int hvwc_dbg_open(struct inode *inode, struct file *file) 119ece4e512SSukadev Bhattiprolu { 120ece4e512SSukadev Bhattiprolu return single_open(file, hvwc_dbg_show, inode->i_private); 121ece4e512SSukadev Bhattiprolu } 122ece4e512SSukadev Bhattiprolu 123ece4e512SSukadev Bhattiprolu static const struct file_operations hvwc_fops = { 124ece4e512SSukadev Bhattiprolu .open = hvwc_dbg_open, 125ece4e512SSukadev Bhattiprolu .read = seq_read, 126ece4e512SSukadev Bhattiprolu .llseek = seq_lseek, 127ece4e512SSukadev Bhattiprolu .release = single_release, 128ece4e512SSukadev Bhattiprolu }; 129ece4e512SSukadev Bhattiprolu 130ece4e512SSukadev Bhattiprolu void vas_window_free_dbgdir(struct vas_window *window) 131ece4e512SSukadev Bhattiprolu { 132ece4e512SSukadev Bhattiprolu if (window->dbgdir) { 133ece4e512SSukadev Bhattiprolu debugfs_remove_recursive(window->dbgdir); 134ece4e512SSukadev Bhattiprolu kfree(window->dbgname); 135ece4e512SSukadev Bhattiprolu window->dbgdir = NULL; 136ece4e512SSukadev Bhattiprolu window->dbgname = NULL; 137ece4e512SSukadev Bhattiprolu } 138ece4e512SSukadev Bhattiprolu } 139ece4e512SSukadev Bhattiprolu 140ece4e512SSukadev Bhattiprolu void vas_window_init_dbgdir(struct vas_window *window) 141ece4e512SSukadev Bhattiprolu { 142ece4e512SSukadev Bhattiprolu struct dentry *f, *d; 143ece4e512SSukadev Bhattiprolu 144ece4e512SSukadev Bhattiprolu if (!window->vinst->dbgdir) 145ece4e512SSukadev Bhattiprolu return; 146ece4e512SSukadev Bhattiprolu 147ece4e512SSukadev Bhattiprolu window->dbgname = kzalloc(16, GFP_KERNEL); 148ece4e512SSukadev Bhattiprolu if (!window->dbgname) 149ece4e512SSukadev Bhattiprolu return; 150ece4e512SSukadev Bhattiprolu 151ece4e512SSukadev Bhattiprolu snprintf(window->dbgname, 16, "w%d", window->winid); 152ece4e512SSukadev Bhattiprolu 153ece4e512SSukadev Bhattiprolu d = debugfs_create_dir(window->dbgname, window->vinst->dbgdir); 154ece4e512SSukadev Bhattiprolu if (IS_ERR(d)) 155ece4e512SSukadev Bhattiprolu goto free_name; 156ece4e512SSukadev Bhattiprolu 157ece4e512SSukadev Bhattiprolu window->dbgdir = d; 158ece4e512SSukadev Bhattiprolu 159ece4e512SSukadev Bhattiprolu f = debugfs_create_file("info", 0444, d, window, &info_fops); 160ece4e512SSukadev Bhattiprolu if (IS_ERR(f)) 161ece4e512SSukadev Bhattiprolu goto remove_dir; 162ece4e512SSukadev Bhattiprolu 163ece4e512SSukadev Bhattiprolu f = debugfs_create_file("hvwc", 0444, d, window, &hvwc_fops); 164ece4e512SSukadev Bhattiprolu if (IS_ERR(f)) 165ece4e512SSukadev Bhattiprolu goto remove_dir; 166ece4e512SSukadev Bhattiprolu 167ece4e512SSukadev Bhattiprolu return; 168ece4e512SSukadev Bhattiprolu 169ece4e512SSukadev Bhattiprolu remove_dir: 170ece4e512SSukadev Bhattiprolu debugfs_remove_recursive(window->dbgdir); 171ece4e512SSukadev Bhattiprolu window->dbgdir = NULL; 1721373cc31SSukadev Bhattiprolu 1731373cc31SSukadev Bhattiprolu free_name: 1741373cc31SSukadev Bhattiprolu kfree(window->dbgname); 1751373cc31SSukadev Bhattiprolu window->dbgname = NULL; 176ece4e512SSukadev Bhattiprolu } 177ece4e512SSukadev Bhattiprolu 178ece4e512SSukadev Bhattiprolu void vas_instance_init_dbgdir(struct vas_instance *vinst) 179ece4e512SSukadev Bhattiprolu { 180ece4e512SSukadev Bhattiprolu struct dentry *d; 181ece4e512SSukadev Bhattiprolu 182*45ddea8aSSukadev Bhattiprolu vas_init_dbgdir(); 183ece4e512SSukadev Bhattiprolu if (!vas_debugfs) 184ece4e512SSukadev Bhattiprolu return; 185ece4e512SSukadev Bhattiprolu 186ece4e512SSukadev Bhattiprolu vinst->dbgname = kzalloc(16, GFP_KERNEL); 187ece4e512SSukadev Bhattiprolu if (!vinst->dbgname) 188ece4e512SSukadev Bhattiprolu return; 189ece4e512SSukadev Bhattiprolu 190ece4e512SSukadev Bhattiprolu snprintf(vinst->dbgname, 16, "v%d", vinst->vas_id); 191ece4e512SSukadev Bhattiprolu 192ece4e512SSukadev Bhattiprolu d = debugfs_create_dir(vinst->dbgname, vas_debugfs); 193ece4e512SSukadev Bhattiprolu if (IS_ERR(d)) 194ece4e512SSukadev Bhattiprolu goto free_name; 195ece4e512SSukadev Bhattiprolu 196ece4e512SSukadev Bhattiprolu vinst->dbgdir = d; 197ece4e512SSukadev Bhattiprolu return; 198ece4e512SSukadev Bhattiprolu 199ece4e512SSukadev Bhattiprolu free_name: 200ece4e512SSukadev Bhattiprolu kfree(vinst->dbgname); 201ece4e512SSukadev Bhattiprolu vinst->dbgname = NULL; 202ece4e512SSukadev Bhattiprolu vinst->dbgdir = NULL; 203ece4e512SSukadev Bhattiprolu } 204ece4e512SSukadev Bhattiprolu 205*45ddea8aSSukadev Bhattiprolu /* 206*45ddea8aSSukadev Bhattiprolu * Set up the "root" VAS debugfs dir. Return if we already set it up 207*45ddea8aSSukadev Bhattiprolu * (or failed to) in an earlier instance of VAS. 208*45ddea8aSSukadev Bhattiprolu */ 209ece4e512SSukadev Bhattiprolu void vas_init_dbgdir(void) 210ece4e512SSukadev Bhattiprolu { 211*45ddea8aSSukadev Bhattiprolu static bool first_time = true; 212*45ddea8aSSukadev Bhattiprolu 213*45ddea8aSSukadev Bhattiprolu if (!first_time) 214*45ddea8aSSukadev Bhattiprolu return; 215*45ddea8aSSukadev Bhattiprolu 216*45ddea8aSSukadev Bhattiprolu first_time = false; 217ece4e512SSukadev Bhattiprolu vas_debugfs = debugfs_create_dir("vas", NULL); 218ece4e512SSukadev Bhattiprolu if (IS_ERR(vas_debugfs)) 219ece4e512SSukadev Bhattiprolu vas_debugfs = NULL; 220ece4e512SSukadev Bhattiprolu } 221