1 // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
2 /*
3 *
4 * (C) COPYRIGHT 2016-2022 ARM Limited. All rights reserved.
5 *
6 * This program is free software and is provided to you under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation, and any use by you of this program is subject to the terms
9 * of such GNU license.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you can access it online at
18 * http://www.gnu.org/licenses/gpl-2.0.html.
19 *
20 */
21
22 #include <linux/debugfs.h>
23
24 #include <mali_kbase.h>
25 #include <mali_kbase_as_fault_debugfs.h>
26 #include <device/mali_kbase_device.h>
27
28 #if IS_ENABLED(CONFIG_DEBUG_FS)
29 #ifdef CONFIG_MALI_BIFROST_DEBUG
30
kbase_as_fault_read(struct seq_file * sfile,void * data)31 static int kbase_as_fault_read(struct seq_file *sfile, void *data)
32 {
33 uintptr_t as_no = (uintptr_t) sfile->private;
34
35 struct list_head *entry;
36 const struct list_head *kbdev_list;
37 struct kbase_device *kbdev = NULL;
38
39 kbdev_list = kbase_device_get_list();
40
41 list_for_each(entry, kbdev_list) {
42 kbdev = list_entry(entry, struct kbase_device, entry);
43
44 if (kbdev->debugfs_as_read_bitmap & (1ULL << as_no)) {
45
46 /* don't show this one again until another fault occors */
47 kbdev->debugfs_as_read_bitmap &= ~(1ULL << as_no);
48
49 /* output the last page fault addr */
50 seq_printf(sfile, "%llu\n",
51 (u64) kbdev->as[as_no].pf_data.addr);
52 }
53
54 }
55
56 kbase_device_put_list(kbdev_list);
57
58 return 0;
59 }
60
kbase_as_fault_debugfs_open(struct inode * in,struct file * file)61 static int kbase_as_fault_debugfs_open(struct inode *in, struct file *file)
62 {
63 return single_open(file, kbase_as_fault_read, in->i_private);
64 }
65
66 static const struct file_operations as_fault_fops = {
67 .owner = THIS_MODULE,
68 .open = kbase_as_fault_debugfs_open,
69 .read = seq_read,
70 .llseek = seq_lseek,
71 .release = single_release,
72 };
73
74 #endif /* CONFIG_MALI_BIFROST_DEBUG */
75 #endif /* CONFIG_DEBUG_FS */
76
77 /*
78 * Initialize debugfs entry for each address space
79 */
kbase_as_fault_debugfs_init(struct kbase_device * kbdev)80 void kbase_as_fault_debugfs_init(struct kbase_device *kbdev)
81 {
82 #if IS_ENABLED(CONFIG_DEBUG_FS)
83 #ifdef CONFIG_MALI_BIFROST_DEBUG
84 uint i;
85 char as_name[64];
86 struct dentry *debugfs_directory;
87
88 kbdev->debugfs_as_read_bitmap = 0ULL;
89
90 KBASE_DEBUG_ASSERT(kbdev->nr_hw_address_spaces);
91 KBASE_DEBUG_ASSERT(sizeof(kbdev->as[0].pf_data.addr) == sizeof(u64));
92
93 debugfs_directory = debugfs_create_dir("address_spaces",
94 kbdev->mali_debugfs_directory);
95
96 if (IS_ERR_OR_NULL(debugfs_directory)) {
97 dev_warn(kbdev->dev,
98 "unable to create address_spaces debugfs directory");
99 } else {
100 for (i = 0; i < kbdev->nr_hw_address_spaces; i++) {
101 if (likely(scnprintf(as_name, ARRAY_SIZE(as_name), "as%u", i)))
102 debugfs_create_file(as_name, 0444, debugfs_directory,
103 (void *)(uintptr_t)i, &as_fault_fops);
104 }
105 }
106
107 #endif /* CONFIG_MALI_BIFROST_DEBUG */
108 #endif /* CONFIG_DEBUG_FS */
109 }
110