16d7d7433SHuang, Ying /* 26d7d7433SHuang, Ying * Architecture specific debugfs files 36d7d7433SHuang, Ying * 46d7d7433SHuang, Ying * Copyright (C) 2007, Intel Corp. 56d7d7433SHuang, Ying * Huang Ying <ying.huang@intel.com> 66d7d7433SHuang, Ying * 76d7d7433SHuang, Ying * This file is released under the GPLv2. 86d7d7433SHuang, Ying */ 96d7d7433SHuang, Ying #include <linux/debugfs.h> 10c14b2adfSHuang, Ying #include <linux/uaccess.h> 11186f4360SPaul Gortmaker #include <linux/export.h> 125a0e3ad6STejun Heo #include <linux/slab.h> 136d7d7433SHuang, Ying #include <linux/init.h> 14390cd85cSJaswinder Singh Rajput #include <linux/stat.h> 15c14b2adfSHuang, Ying #include <linux/io.h> 16c14b2adfSHuang, Ying #include <linux/mm.h> 176d7d7433SHuang, Ying 186d7d7433SHuang, Ying #include <asm/setup.h> 196d7d7433SHuang, Ying 20ae79cdaaSvenkatesh.pallipadi@intel.com struct dentry *arch_debugfs_dir; 21ae79cdaaSvenkatesh.pallipadi@intel.com EXPORT_SYMBOL(arch_debugfs_dir); 22ae79cdaaSvenkatesh.pallipadi@intel.com 236d7d7433SHuang, Ying #ifdef CONFIG_DEBUG_BOOT_PARAMS 24c14b2adfSHuang, Ying struct setup_data_node { 25c14b2adfSHuang, Ying u64 paddr; 26c14b2adfSHuang, Ying u32 type; 27c14b2adfSHuang, Ying u32 len; 28c14b2adfSHuang, Ying }; 29c14b2adfSHuang, Ying 30390cd85cSJaswinder Singh Rajput static ssize_t setup_data_read(struct file *file, char __user *user_buf, 31390cd85cSJaswinder Singh Rajput size_t count, loff_t *ppos) 32c14b2adfSHuang, Ying { 33c14b2adfSHuang, Ying struct setup_data_node *node = file->private_data; 34c14b2adfSHuang, Ying unsigned long remain; 35c14b2adfSHuang, Ying loff_t pos = *ppos; 36c14b2adfSHuang, Ying void *p; 37c14b2adfSHuang, Ying u64 pa; 38c14b2adfSHuang, Ying 39c14b2adfSHuang, Ying if (pos < 0) 40c14b2adfSHuang, Ying return -EINVAL; 41390cd85cSJaswinder Singh Rajput 42c14b2adfSHuang, Ying if (pos >= node->len) 43c14b2adfSHuang, Ying return 0; 44c14b2adfSHuang, Ying 45c14b2adfSHuang, Ying if (count > node->len - pos) 46c14b2adfSHuang, Ying count = node->len - pos; 47390cd85cSJaswinder Singh Rajput 48c14b2adfSHuang, Ying pa = node->paddr + sizeof(struct setup_data) + pos; 49f7750a79STom Lendacky p = memremap(pa, count, MEMREMAP_WB); 50c14b2adfSHuang, Ying if (!p) 51f7750a79STom Lendacky return -ENOMEM; 52c14b2adfSHuang, Ying 53c14b2adfSHuang, Ying remain = copy_to_user(user_buf, p, count); 54c14b2adfSHuang, Ying 55f7750a79STom Lendacky memunmap(p); 56c14b2adfSHuang, Ying 57c14b2adfSHuang, Ying if (remain) 58c14b2adfSHuang, Ying return -EFAULT; 59c14b2adfSHuang, Ying 60c14b2adfSHuang, Ying *ppos = pos + count; 61c14b2adfSHuang, Ying 62c14b2adfSHuang, Ying return count; 63c14b2adfSHuang, Ying } 64c14b2adfSHuang, Ying 65c14b2adfSHuang, Ying static const struct file_operations fops_setup_data = { 66c14b2adfSHuang, Ying .read = setup_data_read, 67234e3405SStephen Boyd .open = simple_open, 686038f373SArnd Bergmann .llseek = default_llseek, 69c14b2adfSHuang, Ying }; 70c14b2adfSHuang, Ying 71*0fc811e5SGreg Kroah-Hartman static void __init 72c14b2adfSHuang, Ying create_setup_data_node(struct dentry *parent, int no, 73c14b2adfSHuang, Ying struct setup_data_node *node) 74c14b2adfSHuang, Ying { 75*0fc811e5SGreg Kroah-Hartman struct dentry *d; 76c14b2adfSHuang, Ying char buf[16]; 77c14b2adfSHuang, Ying 78c14b2adfSHuang, Ying sprintf(buf, "%d", no); 79c14b2adfSHuang, Ying d = debugfs_create_dir(buf, parent); 80390cd85cSJaswinder Singh Rajput 81*0fc811e5SGreg Kroah-Hartman debugfs_create_x32("type", S_IRUGO, d, &node->type); 82*0fc811e5SGreg Kroah-Hartman debugfs_create_file("data", S_IRUGO, d, node, &fops_setup_data); 83c14b2adfSHuang, Ying } 84c14b2adfSHuang, Ying 85c14b2adfSHuang, Ying static int __init create_setup_data_nodes(struct dentry *parent) 86c14b2adfSHuang, Ying { 87c14b2adfSHuang, Ying struct setup_data_node *node; 88c14b2adfSHuang, Ying struct setup_data *data; 8941fb433bSJulia Lawall int error; 90c14b2adfSHuang, Ying struct dentry *d; 91c14b2adfSHuang, Ying u64 pa_data; 92390cd85cSJaswinder Singh Rajput int no = 0; 93c14b2adfSHuang, Ying 94c14b2adfSHuang, Ying d = debugfs_create_dir("setup_data", parent); 95c14b2adfSHuang, Ying 96c14b2adfSHuang, Ying pa_data = boot_params.hdr.setup_data; 97c14b2adfSHuang, Ying 98c14b2adfSHuang, Ying while (pa_data) { 99c14b2adfSHuang, Ying node = kmalloc(sizeof(*node), GFP_KERNEL); 10041fb433bSJulia Lawall if (!node) { 10141fb433bSJulia Lawall error = -ENOMEM; 102c14b2adfSHuang, Ying goto err_dir; 10341fb433bSJulia Lawall } 104390cd85cSJaswinder Singh Rajput 105f7750a79STom Lendacky data = memremap(pa_data, sizeof(*data), MEMREMAP_WB); 106c14b2adfSHuang, Ying if (!data) { 107f461a1d8SJulia Lawall kfree(node); 108f7750a79STom Lendacky error = -ENOMEM; 109c14b2adfSHuang, Ying goto err_dir; 110c14b2adfSHuang, Ying } 111c14b2adfSHuang, Ying 112c14b2adfSHuang, Ying node->paddr = pa_data; 113c14b2adfSHuang, Ying node->type = data->type; 114c14b2adfSHuang, Ying node->len = data->len; 115*0fc811e5SGreg Kroah-Hartman create_setup_data_node(d, no, node); 116c14b2adfSHuang, Ying pa_data = data->next; 117c14b2adfSHuang, Ying 118f7750a79STom Lendacky memunmap(data); 119c14b2adfSHuang, Ying no++; 120c14b2adfSHuang, Ying } 121390cd85cSJaswinder Singh Rajput 122c14b2adfSHuang, Ying return 0; 123c14b2adfSHuang, Ying 124c14b2adfSHuang, Ying err_dir: 125*0fc811e5SGreg Kroah-Hartman debugfs_remove_recursive(d); 126c14b2adfSHuang, Ying return error; 127c14b2adfSHuang, Ying } 128c14b2adfSHuang, Ying 1296d7d7433SHuang, Ying static struct debugfs_blob_wrapper boot_params_blob = { 1306d7d7433SHuang, Ying .data = &boot_params, 1316d7d7433SHuang, Ying .size = sizeof(boot_params), 1326d7d7433SHuang, Ying }; 1336d7d7433SHuang, Ying 1346d7d7433SHuang, Ying static int __init boot_params_kdebugfs_init(void) 1356d7d7433SHuang, Ying { 136*0fc811e5SGreg Kroah-Hartman struct dentry *dbp; 137*0fc811e5SGreg Kroah-Hartman int error; 1386d7d7433SHuang, Ying 13910bce841SBorislav Petkov dbp = debugfs_create_dir("boot_params", arch_debugfs_dir); 140390cd85cSJaswinder Singh Rajput 141*0fc811e5SGreg Kroah-Hartman debugfs_create_x16("version", S_IRUGO, dbp, &boot_params.hdr.version); 142*0fc811e5SGreg Kroah-Hartman debugfs_create_blob("data", S_IRUGO, dbp, &boot_params_blob); 143390cd85cSJaswinder Singh Rajput 144c14b2adfSHuang, Ying error = create_setup_data_nodes(dbp); 145c14b2adfSHuang, Ying if (error) 146*0fc811e5SGreg Kroah-Hartman debugfs_remove_recursive(dbp); 147390cd85cSJaswinder Singh Rajput 1486d7d7433SHuang, Ying return error; 1496d7d7433SHuang, Ying } 150390cd85cSJaswinder Singh Rajput #endif /* CONFIG_DEBUG_BOOT_PARAMS */ 1516d7d7433SHuang, Ying 1526d7d7433SHuang, Ying static int __init arch_kdebugfs_init(void) 1536d7d7433SHuang, Ying { 1546d7d7433SHuang, Ying int error = 0; 1556d7d7433SHuang, Ying 156ae79cdaaSvenkatesh.pallipadi@intel.com arch_debugfs_dir = debugfs_create_dir("x86", NULL); 157ae79cdaaSvenkatesh.pallipadi@intel.com 1586d7d7433SHuang, Ying #ifdef CONFIG_DEBUG_BOOT_PARAMS 1596d7d7433SHuang, Ying error = boot_params_kdebugfs_init(); 1606d7d7433SHuang, Ying #endif 1616d7d7433SHuang, Ying 1626d7d7433SHuang, Ying return error; 1636d7d7433SHuang, Ying } 1646d7d7433SHuang, Ying arch_initcall(arch_kdebugfs_init); 165