On 11 May 2015 at 18:50, Al Stone al.stone@linaro.org wrote:
On 05/11/2015 08:30 AM, Graeme Gregory wrote:
On some architectures /dev/mem is being removed. For debug/analysis tools like FWTS/acpidump we therefore need to expose the ACPI root tables in sysfs like the other tables.
Signed-off-by: Graeme Gregory graeme.gregory@linaro.org
Nicely done.
drivers/acpi/sysfs.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+)
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 0876d77..3f336f9 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -348,6 +348,123 @@ acpi_sysfs_table_handler(u32 event, void *table, void *context) return AE_OK; }
+/*
- On some architectures /dev/mem interface is not available so for debug
- tools like FWTS, acpidump etc we will also need to export the three
- root tables RSDP, RSDT, XSDT where they exist.
- */
+struct acpi_root_table_attr {
struct bin_attribute attr;
acpi_physical_address table_addr;
+};
+static ssize_t acpi_table_show_root(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr, char *buf,
loff_t offset, size_t count)
+{
struct acpi_root_table_attr *table_attr =
container_of(bin_attr,
struct acpi_root_table_attr, attr);
void *table;
int ret;
table = acpi_os_map_memory(table_attr->table_addr, bin_attr->size);
if (!table)
return -EIO;
ret = memory_read_from_buffer(buf, count, &offset, table,
bin_attr->size);
acpi_os_unmap_memory(table, bin_attr->size);
return ret;
+}
+static int acpi_root_tables_sysfs_init(struct kobject *tables_kobj) +{
struct acpi_root_table_attr *root_tables_attr;
struct acpi_table_rsdp *rsdp;
struct acpi_table_header *table_header = NULL;
acpi_physical_address rsdp_ptr, rsdt_ptr, xsdt_ptr;
int ret;
rsdp_ptr = acpi_os_get_root_pointer();
if (!rsdp_ptr)
return -EIO;
rsdp = acpi_os_map_memory(rsdp_ptr, sizeof(*rsdp));
if (!rsdp) {
ret = -EIO;
goto err;
}
root_tables_attr = kzalloc(sizeof(*root_tables_attr) * 3, GFP_KERNEL);
root_tables_attr[0].table_addr = rsdp_ptr;
root_tables_attr[0].attr.size = sizeof(*rsdp);
root_tables_attr[0].attr.read = acpi_table_show_root;
root_tables_attr[0].attr.attr.name = "RSDP";
Minor quibble: technically, this should be "RSD PTR". From a usability standpoint, it's unclear to me which would be better -- "RSD PTR" is the correct signature, but "RSDP" is probably what people expect.
My OE distro seems to be missing acpidump to check what the tool itself actually tries to find!
Graeme
root_tables_attr[0].attr.attr.mode = 0400;
ret = sysfs_create_bin_file(tables_kobj, &root_tables_attr[0].attr);
if (ret)
goto err;
rsdt_ptr = rsdp->rsdt_physical_address;
if (rsdt_ptr) {
table_header = acpi_os_map_memory(rsdt_ptr,
sizeof(*table_header));
if (!table_header) {
ret = -EIO;
goto err;
}
root_tables_attr[1].table_addr = rsdt_ptr;
root_tables_attr[1].attr.size = table_header->length;
root_tables_attr[1].attr.read = acpi_table_show_root;
root_tables_attr[1].attr.attr.name = "RSDT";
root_tables_attr[1].attr.attr.mode = 0400;
ret = sysfs_create_bin_file(tables_kobj,
&root_tables_attr[1].attr);
if (ret)
goto err;
acpi_os_unmap_memory(table_header, sizeof(*table_header));
}
xsdt_ptr = rsdp->xsdt_physical_address;
if (xsdt_ptr) {
table_header = acpi_os_map_memory(xsdt_ptr,
sizeof(*table_header));
if (!table_header) {
ret = -EIO;
goto err;
}
root_tables_attr[2].table_addr = xsdt_ptr;
root_tables_attr[2].attr.size = table_header->length;
root_tables_attr[2].attr.read = acpi_table_show_root;
root_tables_attr[2].attr.attr.name = "XSDT";
root_tables_attr[2].attr.attr.mode = 0400;
ret = sysfs_create_bin_file(tables_kobj,
&root_tables_attr[2].attr);
if (ret)
goto err;
acpi_os_unmap_memory(table_header, sizeof(*table_header));
}
return ret;
+err:
if (rsdp)
acpi_os_map_memory(rsdp_ptr, sizeof(*rsdp));
if (table_header)
acpi_os_unmap_memory(table_header, sizeof(*table_header));
return ret;
+}
static int acpi_tables_sysfs_init(void) { struct acpi_table_attr *table_attr; @@ -387,6 +504,8 @@ static int acpi_tables_sysfs_init(void) list_add_tail(&table_attr->node, &acpi_table_attr_list); }
acpi_root_tables_sysfs_init(tables_kobj);
kobject_uevent(tables_kobj, KOBJ_ADD); kobject_uevent(dynamic_tables_kobj, KOBJ_ADD); status = acpi_install_table_handler(acpi_sysfs_table_handler, NULL);
Other than the above,
Reviewd-by: Al Stone al.stone@linaro.org
-- ciao, al
Al Stone Software Engineer Linaro Enterprise Group al.stone@linaro.org
Linaro-acpi mailing list Linaro-acpi@lists.linaro.org https://lists.linaro.org/mailman/listinfo/linaro-acpi