xref: /openbmc/linux/arch/x86/kernel/kdebugfs.c (revision ae213c44)
1 /*
2  * Architecture specific debugfs files
3  *
4  * Copyright (C) 2007, Intel Corp.
5  *	Huang Ying <ying.huang@intel.com>
6  *
7  * This file is released under the GPLv2.
8  */
9 #include <linux/debugfs.h>
10 #include <linux/uaccess.h>
11 #include <linux/export.h>
12 #include <linux/slab.h>
13 #include <linux/init.h>
14 #include <linux/stat.h>
15 #include <linux/io.h>
16 #include <linux/mm.h>
17 
18 #include <asm/setup.h>
19 
20 struct dentry *arch_debugfs_dir;
21 EXPORT_SYMBOL(arch_debugfs_dir);
22 
23 #ifdef CONFIG_DEBUG_BOOT_PARAMS
24 struct setup_data_node {
25 	u64 paddr;
26 	u32 type;
27 	u32 len;
28 };
29 
30 static ssize_t setup_data_read(struct file *file, char __user *user_buf,
31 			       size_t count, loff_t *ppos)
32 {
33 	struct setup_data_node *node = file->private_data;
34 	unsigned long remain;
35 	loff_t pos = *ppos;
36 	void *p;
37 	u64 pa;
38 
39 	if (pos < 0)
40 		return -EINVAL;
41 
42 	if (pos >= node->len)
43 		return 0;
44 
45 	if (count > node->len - pos)
46 		count = node->len - pos;
47 
48 	pa = node->paddr + sizeof(struct setup_data) + pos;
49 	p = memremap(pa, count, MEMREMAP_WB);
50 	if (!p)
51 		return -ENOMEM;
52 
53 	remain = copy_to_user(user_buf, p, count);
54 
55 	memunmap(p);
56 
57 	if (remain)
58 		return -EFAULT;
59 
60 	*ppos = pos + count;
61 
62 	return count;
63 }
64 
65 static const struct file_operations fops_setup_data = {
66 	.read		= setup_data_read,
67 	.open		= simple_open,
68 	.llseek		= default_llseek,
69 };
70 
71 static int __init
72 create_setup_data_node(struct dentry *parent, int no,
73 		       struct setup_data_node *node)
74 {
75 	struct dentry *d, *type, *data;
76 	char buf[16];
77 
78 	sprintf(buf, "%d", no);
79 	d = debugfs_create_dir(buf, parent);
80 	if (!d)
81 		return -ENOMEM;
82 
83 	type = debugfs_create_x32("type", S_IRUGO, d, &node->type);
84 	if (!type)
85 		goto err_dir;
86 
87 	data = debugfs_create_file("data", S_IRUGO, d, node, &fops_setup_data);
88 	if (!data)
89 		goto err_type;
90 
91 	return 0;
92 
93 err_type:
94 	debugfs_remove(type);
95 err_dir:
96 	debugfs_remove(d);
97 	return -ENOMEM;
98 }
99 
100 static int __init create_setup_data_nodes(struct dentry *parent)
101 {
102 	struct setup_data_node *node;
103 	struct setup_data *data;
104 	int error;
105 	struct dentry *d;
106 	u64 pa_data;
107 	int no = 0;
108 
109 	d = debugfs_create_dir("setup_data", parent);
110 	if (!d)
111 		return -ENOMEM;
112 
113 	pa_data = boot_params.hdr.setup_data;
114 
115 	while (pa_data) {
116 		node = kmalloc(sizeof(*node), GFP_KERNEL);
117 		if (!node) {
118 			error = -ENOMEM;
119 			goto err_dir;
120 		}
121 
122 		data = memremap(pa_data, sizeof(*data), MEMREMAP_WB);
123 		if (!data) {
124 			kfree(node);
125 			error = -ENOMEM;
126 			goto err_dir;
127 		}
128 
129 		node->paddr = pa_data;
130 		node->type = data->type;
131 		node->len = data->len;
132 		error = create_setup_data_node(d, no, node);
133 		pa_data = data->next;
134 
135 		memunmap(data);
136 		if (error)
137 			goto err_dir;
138 		no++;
139 	}
140 
141 	return 0;
142 
143 err_dir:
144 	debugfs_remove(d);
145 	return error;
146 }
147 
148 static struct debugfs_blob_wrapper boot_params_blob = {
149 	.data		= &boot_params,
150 	.size		= sizeof(boot_params),
151 };
152 
153 static int __init boot_params_kdebugfs_init(void)
154 {
155 	struct dentry *dbp, *version, *data;
156 	int error = -ENOMEM;
157 
158 	dbp = debugfs_create_dir("boot_params", arch_debugfs_dir);
159 	if (!dbp)
160 		return -ENOMEM;
161 
162 	version = debugfs_create_x16("version", S_IRUGO, dbp,
163 				     &boot_params.hdr.version);
164 	if (!version)
165 		goto err_dir;
166 
167 	data = debugfs_create_blob("data", S_IRUGO, dbp,
168 				   &boot_params_blob);
169 	if (!data)
170 		goto err_version;
171 
172 	error = create_setup_data_nodes(dbp);
173 	if (error)
174 		goto err_data;
175 
176 	return 0;
177 
178 err_data:
179 	debugfs_remove(data);
180 err_version:
181 	debugfs_remove(version);
182 err_dir:
183 	debugfs_remove(dbp);
184 	return error;
185 }
186 #endif /* CONFIG_DEBUG_BOOT_PARAMS */
187 
188 static int __init arch_kdebugfs_init(void)
189 {
190 	int error = 0;
191 
192 	arch_debugfs_dir = debugfs_create_dir("x86", NULL);
193 	if (!arch_debugfs_dir)
194 		return -ENOMEM;
195 
196 #ifdef CONFIG_DEBUG_BOOT_PARAMS
197 	error = boot_params_kdebugfs_init();
198 #endif
199 
200 	return error;
201 }
202 arch_initcall(arch_kdebugfs_init);
203