|
@@ -9,8 +9,9 @@
|
|
|
* 2 of the License, or (at your option) any later version.
|
|
|
*/
|
|
|
|
|
|
-#undef DEBUG
|
|
|
+#define pr_fmt(fmt) "opal: " fmt
|
|
|
|
|
|
+#include <linux/printk.h>
|
|
|
#include <linux/types.h>
|
|
|
#include <linux/of.h>
|
|
|
#include <linux/of_fdt.h>
|
|
@@ -625,6 +626,39 @@ static int opal_sysfs_init(void)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static ssize_t symbol_map_read(struct file *fp, struct kobject *kobj,
|
|
|
+ struct bin_attribute *bin_attr,
|
|
|
+ char *buf, loff_t off, size_t count)
|
|
|
+{
|
|
|
+ return memory_read_from_buffer(buf, count, &off, bin_attr->private,
|
|
|
+ bin_attr->size);
|
|
|
+}
|
|
|
+
|
|
|
+static BIN_ATTR_RO(symbol_map, 0);
|
|
|
+
|
|
|
+static void opal_export_symmap(void)
|
|
|
+{
|
|
|
+ const __be64 *syms;
|
|
|
+ unsigned int size;
|
|
|
+ struct device_node *fw;
|
|
|
+ int rc;
|
|
|
+
|
|
|
+ fw = of_find_node_by_path("/ibm,opal/firmware");
|
|
|
+ if (!fw)
|
|
|
+ return;
|
|
|
+ syms = of_get_property(fw, "symbol-map", &size);
|
|
|
+ if (!syms || size != 2 * sizeof(__be64))
|
|
|
+ return;
|
|
|
+
|
|
|
+ /* Setup attributes */
|
|
|
+ bin_attr_symbol_map.private = __va(be64_to_cpu(syms[0]));
|
|
|
+ bin_attr_symbol_map.size = be64_to_cpu(syms[1]);
|
|
|
+
|
|
|
+ rc = sysfs_create_bin_file(opal_kobj, &bin_attr_symbol_map);
|
|
|
+ if (rc)
|
|
|
+ pr_warn("Error %d creating OPAL symbols file\n", rc);
|
|
|
+}
|
|
|
+
|
|
|
static void __init opal_dump_region_init(void)
|
|
|
{
|
|
|
void *addr;
|
|
@@ -713,6 +747,8 @@ static int __init opal_init(void)
|
|
|
/* Create "opal" kobject under /sys/firmware */
|
|
|
rc = opal_sysfs_init();
|
|
|
if (rc == 0) {
|
|
|
+ /* Export symbol map to userspace */
|
|
|
+ opal_export_symmap();
|
|
|
/* Setup dump region interface */
|
|
|
opal_dump_region_init();
|
|
|
/* Setup error log interface */
|