1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright 2016-17 IBM Corp. 4 */ 5 6 #define pr_fmt(fmt) "vas: " fmt 7 8 #include <linux/types.h> 9 #include <linux/slab.h> 10 #include <linux/debugfs.h> 11 #include <linux/seq_file.h> 12 #include <asm/vas.h> 13 #include "vas.h" 14 15 static struct dentry *vas_debugfs; 16 17 static char *cop_to_str(int cop) 18 { 19 switch (cop) { 20 case VAS_COP_TYPE_FAULT: return "Fault"; 21 case VAS_COP_TYPE_842: return "NX-842 Normal Priority"; 22 case VAS_COP_TYPE_842_HIPRI: return "NX-842 High Priority"; 23 case VAS_COP_TYPE_GZIP: return "NX-GZIP Normal Priority"; 24 case VAS_COP_TYPE_GZIP_HIPRI: return "NX-GZIP High Priority"; 25 case VAS_COP_TYPE_FTW: return "Fast Thread-wakeup"; 26 default: return "Unknown"; 27 } 28 } 29 30 static int info_show(struct seq_file *s, void *private) 31 { 32 struct pnv_vas_window *window = s->private; 33 34 mutex_lock(&vas_mutex); 35 36 /* ensure window is not unmapped */ 37 if (!window->hvwc_map) 38 goto unlock; 39 40 seq_printf(s, "Type: %s, %s\n", cop_to_str(window->vas_win.cop), 41 window->tx_win ? "Send" : "Receive"); 42 seq_printf(s, "Pid : %d\n", vas_window_pid(&window->vas_win)); 43 44 unlock: 45 mutex_unlock(&vas_mutex); 46 return 0; 47 } 48 49 DEFINE_SHOW_ATTRIBUTE(info); 50 51 static inline void print_reg(struct seq_file *s, struct pnv_vas_window *win, 52 char *name, u32 reg) 53 { 54 seq_printf(s, "0x%016llx %s\n", read_hvwc_reg(win, name, reg), name); 55 } 56 57 static int hvwc_show(struct seq_file *s, void *private) 58 { 59 struct pnv_vas_window *window = s->private; 60 61 mutex_lock(&vas_mutex); 62 63 /* ensure window is not unmapped */ 64 if (!window->hvwc_map) 65 goto unlock; 66 67 print_reg(s, window, VREG(LPID)); 68 print_reg(s, window, VREG(PID)); 69 print_reg(s, window, VREG(XLATE_MSR)); 70 print_reg(s, window, VREG(XLATE_LPCR)); 71 print_reg(s, window, VREG(XLATE_CTL)); 72 print_reg(s, window, VREG(AMR)); 73 print_reg(s, window, VREG(SEIDR)); 74 print_reg(s, window, VREG(FAULT_TX_WIN)); 75 print_reg(s, window, VREG(OSU_INTR_SRC_RA)); 76 print_reg(s, window, VREG(HV_INTR_SRC_RA)); 77 print_reg(s, window, VREG(PSWID)); 78 print_reg(s, window, VREG(LFIFO_BAR)); 79 print_reg(s, window, VREG(LDATA_STAMP_CTL)); 80 print_reg(s, window, VREG(LDMA_CACHE_CTL)); 81 print_reg(s, window, VREG(LRFIFO_PUSH)); 82 print_reg(s, window, VREG(CURR_MSG_COUNT)); 83 print_reg(s, window, VREG(LNOTIFY_AFTER_COUNT)); 84 print_reg(s, window, VREG(LRX_WCRED)); 85 print_reg(s, window, VREG(LRX_WCRED_ADDER)); 86 print_reg(s, window, VREG(TX_WCRED)); 87 print_reg(s, window, VREG(TX_WCRED_ADDER)); 88 print_reg(s, window, VREG(LFIFO_SIZE)); 89 print_reg(s, window, VREG(WINCTL)); 90 print_reg(s, window, VREG(WIN_STATUS)); 91 print_reg(s, window, VREG(WIN_CTX_CACHING_CTL)); 92 print_reg(s, window, VREG(TX_RSVD_BUF_COUNT)); 93 print_reg(s, window, VREG(LRFIFO_WIN_PTR)); 94 print_reg(s, window, VREG(LNOTIFY_CTL)); 95 print_reg(s, window, VREG(LNOTIFY_PID)); 96 print_reg(s, window, VREG(LNOTIFY_LPID)); 97 print_reg(s, window, VREG(LNOTIFY_TID)); 98 print_reg(s, window, VREG(LNOTIFY_SCOPE)); 99 print_reg(s, window, VREG(NX_UTIL_ADDER)); 100 unlock: 101 mutex_unlock(&vas_mutex); 102 return 0; 103 } 104 105 DEFINE_SHOW_ATTRIBUTE(hvwc); 106 107 void vas_window_free_dbgdir(struct pnv_vas_window *pnv_win) 108 { 109 struct vas_window *window = &pnv_win->vas_win; 110 111 if (window->dbgdir) { 112 debugfs_remove_recursive(window->dbgdir); 113 kfree(window->dbgname); 114 window->dbgdir = NULL; 115 window->dbgname = NULL; 116 } 117 } 118 119 void vas_window_init_dbgdir(struct pnv_vas_window *window) 120 { 121 struct dentry *d; 122 123 if (!window->vinst->dbgdir) 124 return; 125 126 window->vas_win.dbgname = kzalloc(16, GFP_KERNEL); 127 if (!window->vas_win.dbgname) 128 return; 129 130 snprintf(window->vas_win.dbgname, 16, "w%d", window->vas_win.winid); 131 132 d = debugfs_create_dir(window->vas_win.dbgname, window->vinst->dbgdir); 133 window->vas_win.dbgdir = d; 134 135 debugfs_create_file("info", 0444, d, window, &info_fops); 136 debugfs_create_file("hvwc", 0444, d, window, &hvwc_fops); 137 } 138 139 void vas_instance_init_dbgdir(struct vas_instance *vinst) 140 { 141 struct dentry *d; 142 143 vas_init_dbgdir(); 144 145 vinst->dbgname = kzalloc(16, GFP_KERNEL); 146 if (!vinst->dbgname) 147 return; 148 149 snprintf(vinst->dbgname, 16, "v%d", vinst->vas_id); 150 151 d = debugfs_create_dir(vinst->dbgname, vas_debugfs); 152 vinst->dbgdir = d; 153 } 154 155 /* 156 * Set up the "root" VAS debugfs dir. Return if we already set it up 157 * (or failed to) in an earlier instance of VAS. 158 */ 159 void vas_init_dbgdir(void) 160 { 161 static bool first_time = true; 162 163 if (!first_time) 164 return; 165 166 first_time = false; 167 vas_debugfs = debugfs_create_dir("vas", NULL); 168 } 169