diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2014-12-10 20:39:49 -0500 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2014-12-14 21:21:44 -0500 |
commit | c8742f85125dcfb27a2daa389283fffebffebb00 (patch) | |
tree | 7447a6567662d40cfcbedcf76633f0ea1fd7f712 /arch/powerpc | |
parent | 77b54e9f213f76a23736940cf94bcd765fc00f40 (diff) |
powerpc/powernv: Expose OPAL firmware symbol map
Newer versions of OPAL will provide this, so let's expose it to user
space so tools like perf can use it to properly decode samples in
firmware space.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/platforms/powernv/opal.c | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index aa316d820736..f10b9ec8c1f5 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c | |||
@@ -9,8 +9,9 @@ | |||
9 | * 2 of the License, or (at your option) any later version. | 9 | * 2 of the License, or (at your option) any later version. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #undef DEBUG | 12 | #define pr_fmt(fmt) "opal: " fmt |
13 | 13 | ||
14 | #include <linux/printk.h> | ||
14 | #include <linux/types.h> | 15 | #include <linux/types.h> |
15 | #include <linux/of.h> | 16 | #include <linux/of.h> |
16 | #include <linux/of_fdt.h> | 17 | #include <linux/of_fdt.h> |
@@ -625,6 +626,39 @@ static int opal_sysfs_init(void) | |||
625 | return 0; | 626 | return 0; |
626 | } | 627 | } |
627 | 628 | ||
629 | static ssize_t symbol_map_read(struct file *fp, struct kobject *kobj, | ||
630 | struct bin_attribute *bin_attr, | ||
631 | char *buf, loff_t off, size_t count) | ||
632 | { | ||
633 | return memory_read_from_buffer(buf, count, &off, bin_attr->private, | ||
634 | bin_attr->size); | ||
635 | } | ||
636 | |||
637 | static BIN_ATTR_RO(symbol_map, 0); | ||
638 | |||
639 | static void opal_export_symmap(void) | ||
640 | { | ||
641 | const __be64 *syms; | ||
642 | unsigned int size; | ||
643 | struct device_node *fw; | ||
644 | int rc; | ||
645 | |||
646 | fw = of_find_node_by_path("/ibm,opal/firmware"); | ||
647 | if (!fw) | ||
648 | return; | ||
649 | syms = of_get_property(fw, "symbol-map", &size); | ||
650 | if (!syms || size != 2 * sizeof(__be64)) | ||
651 | return; | ||
652 | |||
653 | /* Setup attributes */ | ||
654 | bin_attr_symbol_map.private = __va(be64_to_cpu(syms[0])); | ||
655 | bin_attr_symbol_map.size = be64_to_cpu(syms[1]); | ||
656 | |||
657 | rc = sysfs_create_bin_file(opal_kobj, &bin_attr_symbol_map); | ||
658 | if (rc) | ||
659 | pr_warn("Error %d creating OPAL symbols file\n", rc); | ||
660 | } | ||
661 | |||
628 | static void __init opal_dump_region_init(void) | 662 | static void __init opal_dump_region_init(void) |
629 | { | 663 | { |
630 | void *addr; | 664 | void *addr; |
@@ -713,6 +747,8 @@ static int __init opal_init(void) | |||
713 | /* Create "opal" kobject under /sys/firmware */ | 747 | /* Create "opal" kobject under /sys/firmware */ |
714 | rc = opal_sysfs_init(); | 748 | rc = opal_sysfs_init(); |
715 | if (rc == 0) { | 749 | if (rc == 0) { |
750 | /* Export symbol map to userspace */ | ||
751 | opal_export_symmap(); | ||
716 | /* Setup dump region interface */ | 752 | /* Setup dump region interface */ |
717 | opal_dump_region_init(); | 753 | opal_dump_region_init(); |
718 | /* Setup error log interface */ | 754 | /* Setup error log interface */ |